@cerios/salesforce-sobjectly 1.0.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 +21 -13
- package/dist/cli.cjs +4 -4
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +5 -4
- package/dist/cli.mjs.map +1 -1
- package/dist/{codegen-CSx0WAtK.mjs → codegen-0L2ebG9j.mjs} +410 -117
- package/dist/codegen-0L2ebG9j.mjs.map +1 -0
- package/dist/{codegen-BgDgU2RR.cjs → codegen-Daud-Grz.cjs} +419 -112
- package/dist/codegen-Daud-Grz.cjs.map +1 -0
- package/dist/codegen.cjs +3 -1
- package/dist/codegen.d.cts +117 -35
- package/dist/codegen.d.mts +117 -35
- 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-CtWtdkJ0.mjs → sf-cli-D2PgjErx.mjs} +40 -17
- package/dist/sf-cli-D2PgjErx.mjs.map +1 -0
- package/dist/{sf-cli-DEVZQTR7.cjs → sf-cli-S2BrCbik.cjs} +40 -17
- package/dist/sf-cli-S2BrCbik.cjs.map +1 -0
- package/package.json +1 -1
- package/sobjectly.config.schema.json +94 -18
- package/dist/codegen-BgDgU2RR.cjs.map +0 -1
- package/dist/codegen-CSx0WAtK.mjs.map +0 -1
- package/dist/sf-cli-CtWtdkJ0.mjs.map +0 -1
- package/dist/sf-cli-DEVZQTR7.cjs.map +0 -1
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
const require_sf_cli = require("./sf-cli-
|
|
1
|
+
const require_sf_cli = require("./sf-cli-S2BrCbik.cjs");
|
|
2
2
|
let node_crypto = require("node:crypto");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_fs_promises = require("node:fs/promises");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
6
|
let jiti = require("jiti");
|
|
7
7
|
let node_readline = require("node:readline");
|
|
8
|
+
//#region src/codegen/emit.ts
|
|
9
|
+
/** Helpers shared by the modules that emit generated source. */
|
|
10
|
+
const IDENTIFIER$1 = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
11
|
+
/** Fields sorted by name, `Id` first, so the output is deterministic. */
|
|
12
|
+
function sortedFields(describe) {
|
|
13
|
+
return [...describe.fields].sort((a, b) => a.name === "Id" ? -1 : b.name === "Id" ? 1 : compare(a.name, b.name));
|
|
14
|
+
}
|
|
15
|
+
/** An object key: the bare name when it is an identifier, otherwise a quoted string. */
|
|
16
|
+
function propertyKey(name) {
|
|
17
|
+
return IDENTIFIER$1.test(name) ? name : JSON.stringify(name);
|
|
18
|
+
}
|
|
19
|
+
function escapeComment(value) {
|
|
20
|
+
return String(value ?? "").replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
21
|
+
}
|
|
22
|
+
function compare(a, b) {
|
|
23
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
8
26
|
//#region src/codegen/type-mapper.ts
|
|
9
27
|
const ADDRESS_TYPE = "SalesforceAddress";
|
|
10
28
|
const GEOLOCATION_TYPE = "SalesforceGeolocation";
|
|
@@ -39,17 +57,143 @@ const FIELD_TYPE_MAP = {
|
|
|
39
57
|
address: ADDRESS_TYPE,
|
|
40
58
|
location: GEOLOCATION_TYPE
|
|
41
59
|
};
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Returns the TypeScript type for a field, including `| null` for nillable fields. With picklist
|
|
62
|
+
* mode `"const"` or `"enum"`, `typeName` is the field's named picklist type; it replaces the union.
|
|
63
|
+
*/
|
|
64
|
+
function mapFieldType(field, picklists = "union", typeName) {
|
|
65
|
+
const base = picklistType(field, picklists, typeName) ?? FIELD_TYPE_MAP[field.type] ?? "unknown";
|
|
45
66
|
return field.nillable && base !== "unknown" ? `${base} | null` : base;
|
|
46
67
|
}
|
|
47
|
-
function picklistType(field, picklists) {
|
|
48
|
-
if (picklists
|
|
49
|
-
const values =
|
|
68
|
+
function picklistType(field, picklists, typeName) {
|
|
69
|
+
if (picklists === "string" || field.type !== "picklist" && field.type !== "combobox") return;
|
|
70
|
+
const values = activePicklistValues(field);
|
|
50
71
|
if (values.length === 0) return;
|
|
51
|
-
const
|
|
52
|
-
return field.restrictedPicklist && field.type === "picklist" ?
|
|
72
|
+
const members = picklists !== "union" && typeName !== void 0 ? typeName : values.map((value) => JSON.stringify(value)).join(" | ");
|
|
73
|
+
return field.restrictedPicklist && field.type === "picklist" ? members : `${members} | (string & {})`;
|
|
74
|
+
}
|
|
75
|
+
/** The distinct active values of a picklist, multi-select picklist or combobox, in describe order. */
|
|
76
|
+
function activePicklistValues(field) {
|
|
77
|
+
if (field.type !== "picklist" && field.type !== "multipicklist" && field.type !== "combobox") return [];
|
|
78
|
+
return [...new Set((field.picklistValues ?? []).filter((entry) => entry.active).map((entry) => entry.value))];
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/codegen/picklist-types.ts
|
|
82
|
+
function isNamedPicklistMode(mode) {
|
|
83
|
+
return mode === "const" || mode === "enum";
|
|
84
|
+
}
|
|
85
|
+
/** Appended to a picklist type name that is already taken, e.g. by the `CaseStatus` sObject. */
|
|
86
|
+
const CLASH_SUFFIX = "Picklist";
|
|
87
|
+
/**
|
|
88
|
+
* Names the type of every picklist with active values: sObject and field in PascalCase, e.g.
|
|
89
|
+
* `Case.Status` -> `CaseStatus` and `Case.Status__c` -> `CaseStatusCustom`. A name that is in
|
|
90
|
+
* `taken` (the sObjects and other names the file defines) or already used by another picklist gets
|
|
91
|
+
* the suffix `Picklist`; when that is taken too, this throws.
|
|
92
|
+
*/
|
|
93
|
+
function picklistTypeNames(describes, taken) {
|
|
94
|
+
const used = new Map([...taken].map((name) => [name, void 0]));
|
|
95
|
+
const result = /* @__PURE__ */ new Map();
|
|
96
|
+
for (const describe of [...describes].sort((a, b) => compare(a.name, b.name))) {
|
|
97
|
+
const names = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const field of sortedFields(describe).filter((item) => activePicklistValues(item).length > 0)) {
|
|
99
|
+
const base = `${pascalApiName(describe.name, "sobject")}${pascalApiName(field.name, "field")}`;
|
|
100
|
+
if (IDENTIFIER$1.test(base)) {
|
|
101
|
+
const picklist = `${describe.name}.${field.name}`;
|
|
102
|
+
const name = resolveName(base, picklist, used);
|
|
103
|
+
used.set(name, picklist);
|
|
104
|
+
names.set(field.name, name);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (names.size > 0) result.set(describe.name, names);
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
function resolveName(base, picklist, used) {
|
|
112
|
+
const name = used.has(base) ? `${base}${CLASH_SUFFIX}` : base;
|
|
113
|
+
if (used.has(name)) {
|
|
114
|
+
const owner = used.get(name);
|
|
115
|
+
const other = owner === void 0 ? "a type the generated file defines" : `the picklist type for ${owner}`;
|
|
116
|
+
throw new Error(`The picklist type "${name}" for ${picklist} clashes with ${other}; exclude one of the sObjects or use picklists: "union".`);
|
|
117
|
+
}
|
|
118
|
+
return name;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* An API name in PascalCase without underscores. A field's `__c` becomes `Custom`
|
|
122
|
+
* (`Lead_Source__c` -> `LeadSourceCustom`) and an sObject's is dropped (`My_Object__c` ->
|
|
123
|
+
* `MyObject`). Other suffixes are kept: `Foo__pc` -> `FooPc`, `Config__mdt` -> `ConfigMdt`.
|
|
124
|
+
*/
|
|
125
|
+
function pascalApiName(name, kind) {
|
|
126
|
+
const match = /^(.+?)__([a-z]+)$/.exec(name);
|
|
127
|
+
const body = match ? match[1] : name;
|
|
128
|
+
const suffix = match ? match[2] : "";
|
|
129
|
+
const suffixPart = suffix === "c" ? kind === "field" ? "Custom" : "" : capitalize(suffix);
|
|
130
|
+
return `${body.split("_").filter((part) => part.length > 0).map(capitalize).join("")}${suffixPart}`;
|
|
131
|
+
}
|
|
132
|
+
function capitalize(value) {
|
|
133
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The member names for a picklist's values, in the same order. A value that is an identifier is
|
|
137
|
+
* its own name; other values are sanitized (`"Closed Won"` -> `Closed_Won`, `"3rd Party"` ->
|
|
138
|
+
* `_3rd_Party`). When the sanitized name is empty or taken, the value itself is the (quoted) name.
|
|
139
|
+
*/
|
|
140
|
+
function picklistMemberKeys(values, mode) {
|
|
141
|
+
const used = /* @__PURE__ */ new Set();
|
|
142
|
+
const claim = (key) => {
|
|
143
|
+
used.add(key);
|
|
144
|
+
return key;
|
|
145
|
+
};
|
|
146
|
+
const usable = (key) => key.length > 0 && key !== "__proto__" && !used.has(key) && (mode === "const" || !isNumericName(key));
|
|
147
|
+
const own = values.map((value) => IDENTIFIER$1.test(value) && usable(value) ? claim(value) : void 0);
|
|
148
|
+
return values.map((value, index) => {
|
|
149
|
+
const ownKey = own[index];
|
|
150
|
+
if (ownKey !== void 0) return ownKey;
|
|
151
|
+
const sanitized = sanitizeKey(value);
|
|
152
|
+
if (usable(sanitized)) return claim(sanitized);
|
|
153
|
+
if (usable(value)) return claim(value);
|
|
154
|
+
let counter = 2;
|
|
155
|
+
while (!usable(`${sanitized || "_"}_${counter}`)) counter++;
|
|
156
|
+
return claim(`${sanitized || "_"}_${counter}`);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function sanitizeKey(value) {
|
|
160
|
+
const key = value.normalize("NFKD").replace(/\p{M}/gu, "").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
161
|
+
return /^[0-9]/.test(key) ? `_${key}` : key;
|
|
162
|
+
}
|
|
163
|
+
/** Names TypeScript rejects as enum members because they are numeric, e.g. `"1"` or `"-1"`. */
|
|
164
|
+
function isNumericName(key) {
|
|
165
|
+
const number = Number(key);
|
|
166
|
+
return Number.isFinite(number) && String(number) === key;
|
|
167
|
+
}
|
|
168
|
+
/** The named type declarations for one sObject's picklists, in field order; `""` when there are none. */
|
|
169
|
+
function picklistDeclarations(describe, names, mode) {
|
|
170
|
+
if (!names) return "";
|
|
171
|
+
return sortedFields(describe).flatMap((field) => {
|
|
172
|
+
const name = names.get(field.name);
|
|
173
|
+
return name === void 0 ? [] : [declaration(describe.name, field, name, mode)];
|
|
174
|
+
}).join("\n\n");
|
|
175
|
+
}
|
|
176
|
+
function declaration(sobject, field, name, mode) {
|
|
177
|
+
const values = activePicklistValues(field);
|
|
178
|
+
const keys = picklistMemberKeys(values, mode);
|
|
179
|
+
const doc = `/** Active values of ${escapeComment(`${sobject}.${field.name}`)} (${escapeComment(field.type)}). */`;
|
|
180
|
+
if (mode === "enum") {
|
|
181
|
+
const members = values.map((value, index) => `\t${propertyKey(keys[index])} = ${JSON.stringify(value)},`);
|
|
182
|
+
return [
|
|
183
|
+
doc,
|
|
184
|
+
`export enum ${name} {`,
|
|
185
|
+
...members,
|
|
186
|
+
"}"
|
|
187
|
+
].join("\n");
|
|
188
|
+
}
|
|
189
|
+
const members = values.map((value, index) => `\t${propertyKey(keys[index])}: ${JSON.stringify(value)},`);
|
|
190
|
+
return [
|
|
191
|
+
doc,
|
|
192
|
+
`export const ${name} = {`,
|
|
193
|
+
...members,
|
|
194
|
+
"} as const;",
|
|
195
|
+
`export type ${name} = (typeof ${name})[keyof typeof ${name}];`
|
|
196
|
+
].join("\n");
|
|
53
197
|
}
|
|
54
198
|
//#endregion
|
|
55
199
|
//#region src/codegen/generator.ts
|
|
@@ -60,24 +204,28 @@ const FIELD_KINDS = /* @__PURE__ */ new Set([
|
|
|
60
204
|
"time",
|
|
61
205
|
"multipicklist"
|
|
62
206
|
]);
|
|
63
|
-
const IDENTIFIER$1 = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
64
207
|
/**
|
|
65
208
|
* Generates the TypeScript source for a set of sObject describes: a read interface, create
|
|
66
|
-
* and update input types per sObject, and the `SObjectRegistry` that ties them together.
|
|
209
|
+
* and update input types per sObject, and the `SObjectRegistry` that ties them together. With
|
|
210
|
+
* picklist mode `"const"` or `"enum"`, each picklist also gets a named type before its sObject.
|
|
67
211
|
* The output is deterministic: sObjects are sorted by name and fields by name (`Id` first).
|
|
68
212
|
*/
|
|
69
213
|
function generateSource(describes, options = {}) {
|
|
70
214
|
const sorted = [...describes].sort((a, b) => compare(a.name, b.name));
|
|
71
|
-
assertGeneratableNames(sorted);
|
|
215
|
+
const definedNames = assertGeneratableNames(sorted);
|
|
72
216
|
const names = new Set(sorted.map((describe) => describe.name));
|
|
217
|
+
const picklists = options.picklists ?? "union";
|
|
218
|
+
const picklistTypes = isNamedPicklistMode(picklists) ? picklistTypeNames(sorted, definedNames) : void 0;
|
|
73
219
|
const sections = [imports(sorted, options.importSource ?? "@cerios/salesforce-sobjectly")];
|
|
74
220
|
const objectHashes = [];
|
|
75
221
|
for (const describe of sorted) {
|
|
222
|
+
const typeNames = picklistTypes?.get(describe.name);
|
|
76
223
|
const objectSections = [
|
|
77
|
-
|
|
224
|
+
isNamedPicklistMode(picklists) ? picklistDeclarations(describe, typeNames, picklists) : "",
|
|
225
|
+
readInterface(describe, picklists, typeNames),
|
|
78
226
|
inputType(describe, "CreateInput", "createable", lookup(options.excludeCreateFields, describe.name)),
|
|
79
227
|
inputType(describe, "UpdateInput", "updateable", lookup(options.excludeUpdateFields, describe.name))
|
|
80
|
-
];
|
|
228
|
+
].filter((section) => section.length > 0);
|
|
81
229
|
sections.push(...objectSections);
|
|
82
230
|
const fingerprint = [
|
|
83
231
|
...objectSections,
|
|
@@ -104,7 +252,10 @@ const RESERVED_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
|
104
252
|
ADDRESS_TYPE,
|
|
105
253
|
GEOLOCATION_TYPE
|
|
106
254
|
]);
|
|
107
|
-
/**
|
|
255
|
+
/**
|
|
256
|
+
* Fails with a clear message for sObject names the generated TypeScript can't represent. Returns
|
|
257
|
+
* every name the file defines apart from picklist types, so those can avoid them.
|
|
258
|
+
*/
|
|
108
259
|
function assertGeneratableNames(describes) {
|
|
109
260
|
const seen = /* @__PURE__ */ new Map();
|
|
110
261
|
const generated = new Set(describes.flatMap((describe) => [`${describe.name}CreateInput`, `${describe.name}UpdateInput`]));
|
|
@@ -115,6 +266,11 @@ function assertGeneratableNames(describes) {
|
|
|
115
266
|
if (previous !== void 0) throw new Error(`sObjects "${previous}" and "${name}" differ only in case; list each sObject once.`);
|
|
116
267
|
seen.set(name.toLowerCase(), name);
|
|
117
268
|
}
|
|
269
|
+
return /* @__PURE__ */ new Set([
|
|
270
|
+
...RESERVED_TYPE_NAMES,
|
|
271
|
+
...generated,
|
|
272
|
+
...describes.map((describe) => describe.name)
|
|
273
|
+
]);
|
|
118
274
|
}
|
|
119
275
|
/** Looks up a per-sObject option case-insensitively (sObject names are case-insensitive in Salesforce). */
|
|
120
276
|
function lookup(map, name) {
|
|
@@ -162,12 +318,11 @@ function imports(describes, importSource) {
|
|
|
162
318
|
if (fields.some((field) => field.type === "location")) used.push(GEOLOCATION_TYPE);
|
|
163
319
|
return used.length > 0 ? `import type { ${used.join(", ")} } from ${JSON.stringify(importSource)};` : "";
|
|
164
320
|
}
|
|
165
|
-
function
|
|
166
|
-
return [...describe.fields].sort((a, b) => a.name === "Id" ? -1 : b.name === "Id" ? 1 : compare(a.name, b.name));
|
|
167
|
-
}
|
|
168
|
-
function readInterface(describe, picklists) {
|
|
321
|
+
function readInterface(describe, picklists, typeNames) {
|
|
169
322
|
const lines = sortedFields(describe).map((field) => {
|
|
170
|
-
|
|
323
|
+
const comment = `\t/** ${escapeComment(field.label)} (${escapeComment(field.type)}) */`;
|
|
324
|
+
const type = mapFieldType(field, picklists, typeNames?.get(field.name));
|
|
325
|
+
return `${comment}\n\t${propertyKey(field.name)}: ${type};`;
|
|
171
326
|
});
|
|
172
327
|
return `${describe.label ? `/** ${escapeComment(describe.label)} */\n` : ""}export interface ${describe.name} {\n${lines.join("\n")}\n}`;
|
|
173
328
|
}
|
|
@@ -254,10 +409,6 @@ function recordTypeConstants(describes) {
|
|
|
254
409
|
const entries = describes.map((describe) => [describe.name, recordTypeNames(describe)]).filter(([, names]) => names.length > 0).map(([name, names]) => `\t${name}: [${names.map((value) => JSON.stringify(value)).join(", ")}],`);
|
|
255
410
|
return ["/** Record type DeveloperNames per sObject. Resolve ids with `sf.sobject(name).recordTypeId(developerName)`. */", `export const RECORD_TYPES = {${entries.length > 0 ? `\n${entries.join("\n")}\n` : ""}} as const;`].join("\n");
|
|
256
411
|
}
|
|
257
|
-
function activePicklistValues(field) {
|
|
258
|
-
if (field.type !== "picklist" && field.type !== "multipicklist" && field.type !== "combobox") return [];
|
|
259
|
-
return [...new Set((field.picklistValues ?? []).filter((entry) => entry.active).map((entry) => entry.value))];
|
|
260
|
-
}
|
|
261
412
|
function unionOrNever(values) {
|
|
262
413
|
return values.length > 0 ? values.map((value) => JSON.stringify(value)).join(" | ") : "never";
|
|
263
414
|
}
|
|
@@ -280,15 +431,6 @@ function relationshipMap(entries) {
|
|
|
280
431
|
function keyUnion(names) {
|
|
281
432
|
return names.map((name) => JSON.stringify(name)).join(" | ");
|
|
282
433
|
}
|
|
283
|
-
function propertyKey(name) {
|
|
284
|
-
return IDENTIFIER$1.test(name) ? name : JSON.stringify(name);
|
|
285
|
-
}
|
|
286
|
-
function escapeComment(value) {
|
|
287
|
-
return String(value ?? "").replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
288
|
-
}
|
|
289
|
-
function compare(a, b) {
|
|
290
|
-
return a < b ? -1 : a > b ? 1 : 0;
|
|
291
|
-
}
|
|
292
434
|
//#endregion
|
|
293
435
|
//#region src/codegen/validate-config.ts
|
|
294
436
|
/** Thrown when a codegen config is invalid. Lists every problem found. */
|
|
@@ -302,15 +444,28 @@ var CodegenConfigError = class extends Error {
|
|
|
302
444
|
this.problems = problems;
|
|
303
445
|
}
|
|
304
446
|
};
|
|
305
|
-
/** The
|
|
447
|
+
/** The options each auth type accepts: its credential keys, then the deprecated `*Env` keys. */
|
|
306
448
|
const AUTH_OPTIONS = {
|
|
307
449
|
clientCredentials: [
|
|
450
|
+
"loginUrl",
|
|
451
|
+
"clientId",
|
|
452
|
+
"clientSecret",
|
|
308
453
|
"loginUrlEnv",
|
|
309
454
|
"clientIdEnv",
|
|
310
455
|
"clientSecretEnv"
|
|
311
456
|
],
|
|
312
|
-
accessToken: [
|
|
457
|
+
accessToken: [
|
|
458
|
+
"accessToken",
|
|
459
|
+
"instanceUrl",
|
|
460
|
+
"accessTokenEnv",
|
|
461
|
+
"instanceUrlEnv"
|
|
462
|
+
],
|
|
313
463
|
jwtBearer: [
|
|
464
|
+
"loginUrl",
|
|
465
|
+
"clientId",
|
|
466
|
+
"username",
|
|
467
|
+
"privateKey",
|
|
468
|
+
"privateKeyPath",
|
|
314
469
|
"loginUrlEnv",
|
|
315
470
|
"clientIdEnv",
|
|
316
471
|
"usernameEnv",
|
|
@@ -319,7 +474,23 @@ const AUTH_OPTIONS = {
|
|
|
319
474
|
],
|
|
320
475
|
sfCli: ["targetOrg"]
|
|
321
476
|
};
|
|
322
|
-
|
|
477
|
+
/** The deprecated `*Env` auth options, each mapped to the credential key that replaces it. */
|
|
478
|
+
const DEPRECATED_AUTH_OPTIONS = {
|
|
479
|
+
loginUrlEnv: "loginUrl",
|
|
480
|
+
clientIdEnv: "clientId",
|
|
481
|
+
clientSecretEnv: "clientSecret",
|
|
482
|
+
accessTokenEnv: "accessToken",
|
|
483
|
+
instanceUrlEnv: "instanceUrl",
|
|
484
|
+
usernameEnv: "username",
|
|
485
|
+
privateKeyEnv: "privateKey",
|
|
486
|
+
privateKeyPathEnv: "privateKeyPath"
|
|
487
|
+
};
|
|
488
|
+
const PICKLIST_MODES = [
|
|
489
|
+
"union",
|
|
490
|
+
"string",
|
|
491
|
+
"const",
|
|
492
|
+
"enum"
|
|
493
|
+
];
|
|
323
494
|
const IDENTIFIER = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
324
495
|
const VALIDATORS = {
|
|
325
496
|
$schema: (value, { problem }) => {
|
|
@@ -339,7 +510,7 @@ const VALIDATORS = {
|
|
|
339
510
|
excludeCreateFields: (value, context) => validateFieldMap("excludeCreateFields", value, context),
|
|
340
511
|
excludeUpdateFields: (value, context) => validateFieldMap("excludeUpdateFields", value, context),
|
|
341
512
|
picklists: (value, { problem }) => {
|
|
342
|
-
if (!PICKLIST_MODES.includes(value)) problem(`picklists: must be
|
|
513
|
+
if (!PICKLIST_MODES.includes(value)) problem(`picklists: must be one of ${PICKLIST_MODES.join(", ")}, got ${show(value)}.`);
|
|
343
514
|
},
|
|
344
515
|
constants: (value, { problem }) => {
|
|
345
516
|
if (typeof value !== "boolean") problem(`constants: must be true or false, got ${show(value)}.`);
|
|
@@ -425,8 +596,17 @@ function validateAuth(value, { json, problem }) {
|
|
|
425
596
|
problem(`auth.type: must be one of ${Object.keys(AUTH_OPTIONS).join(", ")}, got ${show(type)}.`);
|
|
426
597
|
return;
|
|
427
598
|
}
|
|
428
|
-
for (const [key, option] of Object.entries(rest)) if (!allowed.includes(key))
|
|
429
|
-
|
|
599
|
+
for (const [key, option] of Object.entries(rest)) if (!allowed.includes(key)) {
|
|
600
|
+
const valid = allowed.filter((name) => !(name in DEPRECATED_AUTH_OPTIONS));
|
|
601
|
+
problem(`auth.${key}: not an option of "${String(type)}". Valid options: ${valid.join(", ")}.`);
|
|
602
|
+
} else validateAuthOption(key, option, rest, problem);
|
|
603
|
+
}
|
|
604
|
+
function validateAuthOption(key, option, setting, problem) {
|
|
605
|
+
const replacement = DEPRECATED_AUTH_OPTIONS[key];
|
|
606
|
+
if (replacement !== void 0 && replacement in setting) problem(`auth.${key}: use either ${replacement} or ${key}, not both.`);
|
|
607
|
+
else if (replacement !== void 0) {
|
|
608
|
+
if (typeof option !== "string" || option.length === 0) problem(`auth.${key}: must be a non-empty string, got ${show(option)}.`);
|
|
609
|
+
} else if (option !== void 0 && typeof option !== "string") problem(`auth.${key}: must be a string, got ${show(option)}.`);
|
|
430
610
|
}
|
|
431
611
|
function show(value) {
|
|
432
612
|
if (value === void 0) return "undefined";
|
|
@@ -438,24 +618,6 @@ function show(value) {
|
|
|
438
618
|
}
|
|
439
619
|
}
|
|
440
620
|
//#endregion
|
|
441
|
-
//#region src/codegen/config.ts
|
|
442
|
-
/**
|
|
443
|
-
* Type-checks a `sobjectly.config.ts`. The listed `sobjects` become a literal union, so a typo in
|
|
444
|
-
* a per-sObject option is a compile error:
|
|
445
|
-
*
|
|
446
|
-
* ```ts
|
|
447
|
-
* export default defineConfig({
|
|
448
|
-
* apiVersion: "v66.0",
|
|
449
|
-
* output: "src/generated/sobjects.ts",
|
|
450
|
-
* sobjects: ["Account", "Contact"],
|
|
451
|
-
* excludeCreateFields: { Acount: ["Name"] }, // ❌ "Acount" is not in sobjects
|
|
452
|
-
* });
|
|
453
|
-
* ```
|
|
454
|
-
*/
|
|
455
|
-
function defineConfig(config) {
|
|
456
|
-
return config;
|
|
457
|
-
}
|
|
458
|
-
//#endregion
|
|
459
621
|
//#region src/codegen/load-config.ts
|
|
460
622
|
/** Config file names, in lookup order. */
|
|
461
623
|
const CONFIG_FILE_NAMES = [
|
|
@@ -507,25 +669,50 @@ function readJson(path) {
|
|
|
507
669
|
}
|
|
508
670
|
}
|
|
509
671
|
//#endregion
|
|
672
|
+
//#region src/codegen/config.ts
|
|
673
|
+
/**
|
|
674
|
+
* Type-checks a `sobjectly.config.ts`. The listed `sobjects` become a literal union, so a typo in
|
|
675
|
+
* a per-sObject option is a compile error:
|
|
676
|
+
*
|
|
677
|
+
* ```ts
|
|
678
|
+
* export default defineConfig({
|
|
679
|
+
* apiVersion: "v66.0",
|
|
680
|
+
* output: "src/generated/sobjects.ts",
|
|
681
|
+
* sobjects: ["Account", "Contact"],
|
|
682
|
+
* excludeCreateFields: { Acount: ["Name"] }, // ❌ "Acount" is not in sobjects
|
|
683
|
+
* });
|
|
684
|
+
* ```
|
|
685
|
+
*/
|
|
686
|
+
function defineConfig(config) {
|
|
687
|
+
return config;
|
|
688
|
+
}
|
|
689
|
+
//#endregion
|
|
510
690
|
//#region src/codegen/init.ts
|
|
511
691
|
const SOBJECT_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
512
692
|
const NPM_SCRIPT = "sobjects:generate";
|
|
513
|
-
/** The
|
|
514
|
-
const
|
|
693
|
+
/** The credential keys `init` writes per auth type, each with the environment variable it suggests. */
|
|
694
|
+
const AUTH_FIELDS = {
|
|
515
695
|
clientCredentials: [
|
|
516
|
-
"SF_LOGIN_URL",
|
|
517
|
-
"SF_CLIENT_ID",
|
|
518
|
-
"SF_CLIENT_SECRET"
|
|
696
|
+
["loginUrl", "SF_LOGIN_URL"],
|
|
697
|
+
["clientId", "SF_CLIENT_ID"],
|
|
698
|
+
["clientSecret", "SF_CLIENT_SECRET"]
|
|
519
699
|
],
|
|
520
|
-
accessToken: ["SF_ACCESS_TOKEN", "SF_INSTANCE_URL"],
|
|
700
|
+
accessToken: [["accessToken", "SF_ACCESS_TOKEN"], ["instanceUrl", "SF_INSTANCE_URL"]],
|
|
521
701
|
jwtBearer: [
|
|
522
|
-
"SF_LOGIN_URL",
|
|
523
|
-
"SF_CLIENT_ID",
|
|
524
|
-
"SF_USERNAME",
|
|
525
|
-
"SF_PRIVATE_KEY_PATH"
|
|
702
|
+
["loginUrl", "SF_LOGIN_URL"],
|
|
703
|
+
["clientId", "SF_CLIENT_ID"],
|
|
704
|
+
["username", "SF_USERNAME"],
|
|
705
|
+
["privateKeyPath", "SF_PRIVATE_KEY_PATH"]
|
|
526
706
|
],
|
|
527
707
|
sfCli: []
|
|
528
708
|
};
|
|
709
|
+
/** The environment variables the config written by `init` reads, per auth type. */
|
|
710
|
+
const AUTH_ENV_VARS = {
|
|
711
|
+
clientCredentials: AUTH_FIELDS.clientCredentials.map(([, envName]) => envName),
|
|
712
|
+
accessToken: AUTH_FIELDS.accessToken.map(([, envName]) => envName),
|
|
713
|
+
jwtBearer: AUTH_FIELDS.jwtBearer.map(([, envName]) => envName),
|
|
714
|
+
sfCli: []
|
|
715
|
+
};
|
|
529
716
|
const AUTH_CHOICES = [
|
|
530
717
|
{
|
|
531
718
|
value: "clientCredentials",
|
|
@@ -544,13 +731,24 @@ const AUTH_CHOICES = [
|
|
|
544
731
|
label: "JWT bearer (certificate-based, runs as a user)"
|
|
545
732
|
}
|
|
546
733
|
];
|
|
547
|
-
const PICKLIST_CHOICES = [
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
734
|
+
const PICKLIST_CHOICES = [
|
|
735
|
+
{
|
|
736
|
+
value: "union",
|
|
737
|
+
label: "Union of values, e.g. \"New\" | \"Closed\" (type-safe)"
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
value: "string",
|
|
741
|
+
label: "Plain string"
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
value: "const",
|
|
745
|
+
label: "Union plus a named constant per picklist, e.g. CaseStatus.Closed"
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
value: "enum",
|
|
749
|
+
label: "TypeScript enum per picklist (restricted picklists only accept enum members)"
|
|
750
|
+
}
|
|
751
|
+
];
|
|
554
752
|
const FORMAT_CHOICES = [{
|
|
555
753
|
value: "ts",
|
|
556
754
|
label: "TypeScript (sobjectly.config.ts, type-checked with defineConfig)"
|
|
@@ -673,7 +871,6 @@ function renderJsonConfig(answers) {
|
|
|
673
871
|
return `${JSON.stringify(config, null, " ")}\n`;
|
|
674
872
|
}
|
|
675
873
|
function renderTypeScriptConfig(answers) {
|
|
676
|
-
const envVars = AUTH_ENV_VARS[answers.auth];
|
|
677
874
|
const sobjects = answers.sobjects.map((name) => JSON.stringify(name)).join(", ");
|
|
678
875
|
return [
|
|
679
876
|
"import { defineConfig } from \"@cerios/salesforce-sobjectly/codegen\";",
|
|
@@ -685,26 +882,38 @@ function renderTypeScriptConfig(answers) {
|
|
|
685
882
|
`\toutput: ${JSON.stringify(answers.output)},`,
|
|
686
883
|
" // The sObjects to generate types for.",
|
|
687
884
|
`\tsobjects: [${sobjects}],`,
|
|
688
|
-
`\t// ${authComment(answers.auth
|
|
885
|
+
`\t// ${authComment(answers.auth)}`,
|
|
689
886
|
`\tauth: ${renderAuth(answers)},`,
|
|
690
887
|
`\tpicklists: ${JSON.stringify(answers.picklists)},`,
|
|
691
888
|
"});",
|
|
692
889
|
""
|
|
693
890
|
].join("\n");
|
|
694
891
|
}
|
|
892
|
+
/** The JSON auth setting: credentials are `"${NAME}"` placeholders, read from the environment. */
|
|
695
893
|
function authSetting(answers) {
|
|
696
|
-
|
|
894
|
+
if (answers.auth === "sfCli") return answers.targetOrg ? {
|
|
697
895
|
type: "sfCli",
|
|
698
896
|
targetOrg: answers.targetOrg
|
|
699
|
-
} : { type:
|
|
897
|
+
} : { type: "sfCli" };
|
|
898
|
+
const fields = AUTH_FIELDS[answers.auth].map(([key, envName]) => [key, `\${${envName}}`]);
|
|
899
|
+
return {
|
|
900
|
+
type: answers.auth,
|
|
901
|
+
...Object.fromEntries(fields)
|
|
902
|
+
};
|
|
700
903
|
}
|
|
904
|
+
/** The TypeScript auth setting: credentials are read with `process.env`. */
|
|
701
905
|
function renderAuth(answers) {
|
|
702
|
-
|
|
703
|
-
const
|
|
704
|
-
return
|
|
906
|
+
if (answers.auth === "sfCli") return `{ type: "sfCli"${answers.targetOrg ? `, targetOrg: ${JSON.stringify(answers.targetOrg)}` : ""} }`;
|
|
907
|
+
const fields = AUTH_FIELDS[answers.auth].map(([key, envName]) => `\t\t${key}: process.env.${envName},`);
|
|
908
|
+
return [
|
|
909
|
+
"{",
|
|
910
|
+
`\t\ttype: ${JSON.stringify(answers.auth)},`,
|
|
911
|
+
...fields,
|
|
912
|
+
" }"
|
|
913
|
+
].join("\n");
|
|
705
914
|
}
|
|
706
|
-
function authComment(auth
|
|
707
|
-
return auth === "sfCli" ? "Uses an org you are logged into with the Salesforce CLI (sf org login web)." :
|
|
915
|
+
function authComment(auth) {
|
|
916
|
+
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.";
|
|
708
917
|
}
|
|
709
918
|
async function maybeUpdateEnvExample(options, auth) {
|
|
710
919
|
const path = (0, node_path.join)(options.cwd, ".env.example");
|
|
@@ -754,9 +963,10 @@ function printNextSteps(log, answers, scriptAdded, cwd) {
|
|
|
754
963
|
"Next steps:",
|
|
755
964
|
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)"}.`,
|
|
756
965
|
` 2. Generate the types: ${command}`,
|
|
757
|
-
" 3. Use them:",
|
|
966
|
+
" 3. Use them, logging in with the config's auth:",
|
|
967
|
+
" import { loadAuth } from \"@cerios/salesforce-sobjectly/codegen\";",
|
|
758
968
|
` import { API_VERSION, type SObjectRegistry } from "./${answers.output.replace(/\.(ts|mts|cts)$/, "")}";`,
|
|
759
|
-
" const sf = new SalesforceClient<SObjectRegistry>({ apiVersion: API_VERSION, auth });"
|
|
969
|
+
" const sf = new SalesforceClient<SObjectRegistry>({ apiVersion: API_VERSION, auth: await loadAuth() });"
|
|
760
970
|
].join("\n"));
|
|
761
971
|
}
|
|
762
972
|
function formatList(items) {
|
|
@@ -923,7 +1133,7 @@ async function buildSource(input, options) {
|
|
|
923
1133
|
const env = options.env ?? process.env;
|
|
924
1134
|
const outputPath = (0, node_path.isAbsolute)(config.output) ? config.output : (0, node_path.resolve)(options.cwd ?? process.cwd(), config.output);
|
|
925
1135
|
const client = new require_sf_cli.SalesforceClient({
|
|
926
|
-
auth: resolveAuth(config.auth, env),
|
|
1136
|
+
auth: resolveAuth(config.auth, env, { warn: (message) => logger.warn(message) }),
|
|
927
1137
|
apiVersion,
|
|
928
1138
|
transport: config.transport,
|
|
929
1139
|
retry: true
|
|
@@ -976,39 +1186,118 @@ function normalizeSource(source) {
|
|
|
976
1186
|
}
|
|
977
1187
|
return result;
|
|
978
1188
|
}
|
|
979
|
-
/**
|
|
980
|
-
|
|
1189
|
+
/** Where the JWT private key comes from, in order of preference, with each default variable. */
|
|
1190
|
+
const PRIVATE_KEY_SOURCES = [["privateKey", "SF_PRIVATE_KEY"], ["privateKeyPath", "SF_PRIVATE_KEY_PATH"]];
|
|
1191
|
+
/** A `"${NAME}"` placeholder. Only a whole value counts, so a secret that contains `${` is kept as-is. */
|
|
1192
|
+
const ENV_PLACEHOLDER = /^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/;
|
|
1193
|
+
/**
|
|
1194
|
+
* Turns the config's auth setting into an auth provider. Each credential comes from its key in
|
|
1195
|
+
* the setting (a `"${NAME}"` placeholder is read from `env`), else from the variable a deprecated
|
|
1196
|
+
* `*Env` key names, else from its default `SF_*` variable. Throws one error listing every
|
|
1197
|
+
* missing credential.
|
|
1198
|
+
*/
|
|
1199
|
+
function resolveAuth(auth, env, options = {}) {
|
|
981
1200
|
const setting = auth ?? { type: "clientCredentials" };
|
|
982
1201
|
if ("getToken" in setting) return setting;
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
1202
|
+
const problems = [];
|
|
1203
|
+
const lookup = (key, defaultEnv) => readCredential(setting, key, defaultEnv, env, options.warn);
|
|
1204
|
+
const read = (key, defaultEnv) => {
|
|
1205
|
+
const { value, problem } = lookup(key, defaultEnv);
|
|
1206
|
+
if (problem) problems.push(problem);
|
|
986
1207
|
return value;
|
|
987
1208
|
};
|
|
988
1209
|
switch (setting.type) {
|
|
989
|
-
case "accessToken":
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1210
|
+
case "accessToken": {
|
|
1211
|
+
const token = {
|
|
1212
|
+
accessToken: read("accessToken", "SF_ACCESS_TOKEN"),
|
|
1213
|
+
instanceUrl: read("instanceUrl", "SF_INSTANCE_URL")
|
|
1214
|
+
};
|
|
1215
|
+
throwIfMissing(setting.type, problems);
|
|
1216
|
+
return require_sf_cli.accessToken(token);
|
|
1217
|
+
}
|
|
1218
|
+
case "jwtBearer": {
|
|
1219
|
+
const loginUrl = read("loginUrl", "SF_LOGIN_URL");
|
|
1220
|
+
const clientId = read("clientId", "SF_CLIENT_ID");
|
|
1221
|
+
const username = read("username", "SF_USERNAME");
|
|
1222
|
+
const configured = PRIVATE_KEY_SOURCES.filter(([key]) => key in setting);
|
|
1223
|
+
const found = (configured.length > 0 ? configured : PRIVATE_KEY_SOURCES).map(([key, defaultEnv]) => ({
|
|
1224
|
+
key,
|
|
1225
|
+
...lookup(key, defaultEnv)
|
|
1226
|
+
}));
|
|
1227
|
+
const source = found.find((item) => item.value);
|
|
1228
|
+
if (source === void 0) problems.push(`no private key: ${found.map((item) => item.problem).join(", and ")}`);
|
|
1229
|
+
throwIfMissing(setting.type, problems);
|
|
1230
|
+
const privateKey = source?.key === "privateKeyPath" ? (0, node_fs.readFileSync)(source.value, "utf8") : source?.value ?? "";
|
|
1231
|
+
return require_sf_cli.jwtBearer({
|
|
1232
|
+
loginUrl,
|
|
1233
|
+
clientId,
|
|
1234
|
+
username,
|
|
1235
|
+
privateKey
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
case "sfCli": {
|
|
1239
|
+
const targetOrg = "targetOrg" in setting ? read("targetOrg", "") : void 0;
|
|
1240
|
+
throwIfMissing(setting.type, problems);
|
|
1241
|
+
return require_sf_cli.sfCli({ targetOrg });
|
|
1242
|
+
}
|
|
1243
|
+
case "clientCredentials": {
|
|
1244
|
+
const credentials = {
|
|
1245
|
+
loginUrl: read("loginUrl", "SF_LOGIN_URL"),
|
|
1246
|
+
clientId: read("clientId", "SF_CLIENT_ID"),
|
|
1247
|
+
clientSecret: read("clientSecret", "SF_CLIENT_SECRET")
|
|
1248
|
+
};
|
|
1249
|
+
throwIfMissing(setting.type, problems);
|
|
1250
|
+
return require_sf_cli.clientCredentials(credentials);
|
|
1251
|
+
}
|
|
1000
1252
|
default: throw new Error(`Unknown codegen auth type "${setting.type}".`);
|
|
1001
1253
|
}
|
|
1002
1254
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1255
|
+
/**
|
|
1256
|
+
* Loads the sobjectly config and returns an auth provider for its `auth` setting, so the client
|
|
1257
|
+
* logs in the same way as `sobjectly generate`:
|
|
1258
|
+
* `new SalesforceClient({ apiVersion: API_VERSION, auth: await loadAuth() })`.
|
|
1259
|
+
* Throws when no config file is found, or one error listing every missing credential.
|
|
1260
|
+
*/
|
|
1261
|
+
async function loadAuth(options = {}) {
|
|
1262
|
+
const cwd = options.cwd ?? process.cwd();
|
|
1263
|
+
let configPath = options.configPath === void 0 ? void 0 : (0, node_path.resolve)(cwd, options.configPath);
|
|
1264
|
+
if (configPath === void 0) {
|
|
1265
|
+
const found = findConfigFiles(cwd);
|
|
1266
|
+
if (found.length > 1) options.warn?.(`found ${found.join(" and ")}; using ${found[0]}. Remove the other one.`);
|
|
1267
|
+
configPath = found[0];
|
|
1268
|
+
}
|
|
1269
|
+
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.`);
|
|
1270
|
+
const { config } = await loadConfig(configPath);
|
|
1271
|
+
return resolveAuth(config.auth, options.env ?? process.env, { warn: options.warn });
|
|
1272
|
+
}
|
|
1273
|
+
function readCredential(setting, key, defaultEnv, env, warn) {
|
|
1274
|
+
const values = setting;
|
|
1275
|
+
if (key in values) {
|
|
1276
|
+
const configured = values[key];
|
|
1277
|
+
const name = typeof configured === "string" ? ENV_PLACEHOLDER.exec(configured)?.[1] : void 0;
|
|
1278
|
+
if (name !== void 0) return fromEnv(env, name, ` (from auth.${key} "${String(configured)}")`);
|
|
1279
|
+
return typeof configured === "string" && configured.length > 0 ? { value: configured } : {
|
|
1280
|
+
value: "",
|
|
1281
|
+
problem: `auth.${key} is empty or undefined (if it reads process.env, that variable is not set)`
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
const envKey = `${key}Env`;
|
|
1285
|
+
const legacy = values[envKey];
|
|
1286
|
+
if (typeof legacy === "string") {
|
|
1287
|
+
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.`);
|
|
1288
|
+
return fromEnv(env, legacy, "");
|
|
1289
|
+
}
|
|
1290
|
+
return fromEnv(env, defaultEnv, "");
|
|
1291
|
+
}
|
|
1292
|
+
function fromEnv(env, name, origin) {
|
|
1293
|
+
const value = env[name];
|
|
1294
|
+
return value ? { value } : {
|
|
1295
|
+
value: "",
|
|
1296
|
+
problem: `environment variable ${name}${origin} is not set`
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
function throwIfMissing(type, problems) {
|
|
1300
|
+
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).`);
|
|
1012
1301
|
}
|
|
1013
1302
|
async function resolveSObjectNames(client, config, logger) {
|
|
1014
1303
|
const exclude = new Set((config.exclude ?? []).map((name) => name.toLowerCase()));
|
|
@@ -1109,12 +1398,24 @@ Object.defineProperty(exports, "CodegenConfigError", {
|
|
|
1109
1398
|
return CodegenConfigError;
|
|
1110
1399
|
}
|
|
1111
1400
|
});
|
|
1401
|
+
Object.defineProperty(exports, "DEPRECATED_AUTH_OPTIONS", {
|
|
1402
|
+
enumerable: true,
|
|
1403
|
+
get: function() {
|
|
1404
|
+
return DEPRECATED_AUTH_OPTIONS;
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1112
1407
|
Object.defineProperty(exports, "FIELD_TYPE_MAP", {
|
|
1113
1408
|
enumerable: true,
|
|
1114
1409
|
get: function() {
|
|
1115
1410
|
return FIELD_TYPE_MAP;
|
|
1116
1411
|
}
|
|
1117
1412
|
});
|
|
1413
|
+
Object.defineProperty(exports, "PICKLIST_MODES", {
|
|
1414
|
+
enumerable: true,
|
|
1415
|
+
get: function() {
|
|
1416
|
+
return PICKLIST_MODES;
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1118
1419
|
Object.defineProperty(exports, "checkGenerated", {
|
|
1119
1420
|
enumerable: true,
|
|
1120
1421
|
get: function() {
|
|
@@ -1151,6 +1452,12 @@ Object.defineProperty(exports, "generateSource", {
|
|
|
1151
1452
|
return generateSource;
|
|
1152
1453
|
}
|
|
1153
1454
|
});
|
|
1455
|
+
Object.defineProperty(exports, "loadAuth", {
|
|
1456
|
+
enumerable: true,
|
|
1457
|
+
get: function() {
|
|
1458
|
+
return loadAuth;
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1154
1461
|
Object.defineProperty(exports, "loadConfig", {
|
|
1155
1462
|
enumerable: true,
|
|
1156
1463
|
get: function() {
|
|
@@ -1206,4 +1513,4 @@ Object.defineProperty(exports, "validateConfig", {
|
|
|
1206
1513
|
}
|
|
1207
1514
|
});
|
|
1208
1515
|
|
|
1209
|
-
//# sourceMappingURL=codegen-
|
|
1516
|
+
//# sourceMappingURL=codegen-Daud-Grz.cjs.map
|