@cerios/salesforce-sobjectly 1.0.0 → 1.1.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 +1 -1
- 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-BgDgU2RR.cjs → codegen-Bylrt2Ju.cjs} +207 -43
- package/dist/codegen-Bylrt2Ju.cjs.map +1 -0
- package/dist/{codegen-CSx0WAtK.mjs → codegen-C6MEYiWo.mjs} +211 -45
- package/dist/codegen-C6MEYiWo.mjs.map +1 -0
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.d.cts +19 -4
- package/dist/codegen.d.mts +19 -4
- package/dist/codegen.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{sf-cli-DEVZQTR7.cjs → sf-cli-R6LHwqoo.cjs} +8 -5
- package/dist/{sf-cli-DEVZQTR7.cjs.map → sf-cli-R6LHwqoo.cjs.map} +1 -1
- package/dist/{sf-cli-CtWtdkJ0.mjs → sf-cli-_Ua-M_Zi.mjs} +8 -5
- package/dist/{sf-cli-CtWtdkJ0.mjs.map → sf-cli-_Ua-M_Zi.mjs.map} +1 -1
- package/package.json +1 -1
- package/sobjectly.config.schema.json +2 -2
- package/dist/codegen-BgDgU2RR.cjs.map +0 -1
- package/dist/codegen-CSx0WAtK.mjs.map +0 -1
|
@@ -1,22 +1,50 @@
|
|
|
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-_Ua-M_Zi.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";
|
|
5
5
|
import { dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
6
6
|
import { createJiti } from "jiti";
|
|
7
7
|
import { createInterface } from "node:readline";
|
|
8
|
+
//#region src/codegen/emit.ts
|
|
9
|
+
/** Fields sorted by name, `Id` first, so the output is deterministic. */
|
|
10
|
+
function sortedFields(describe) {
|
|
11
|
+
return [...describe.fields].sort((a, b) => a.name === "Id" ? -1 : b.name === "Id" ? 1 : compare(a.name, b.name));
|
|
12
|
+
}
|
|
13
|
+
/** An object key: the bare name when it is an identifier, otherwise a quoted string. */
|
|
14
|
+
function propertyKey(name) {
|
|
15
|
+
return IDENTIFIER$1.test(name) ? name : JSON.stringify(name);
|
|
16
|
+
}
|
|
17
|
+
function escapeComment(value) {
|
|
18
|
+
return String(value ?? "").replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
19
|
+
}
|
|
20
|
+
function compare(a, b) {
|
|
21
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
22
|
+
}
|
|
23
|
+
var IDENTIFIER$1;
|
|
24
|
+
var init_emit = __esmMin((() => {
|
|
25
|
+
IDENTIFIER$1 = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
26
|
+
}));
|
|
27
|
+
//#endregion
|
|
8
28
|
//#region src/codegen/type-mapper.ts
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Returns the TypeScript type for a field, including `| null` for nillable fields. With picklist
|
|
31
|
+
* mode `"const"` or `"enum"`, `typeName` is the field's named picklist type; it replaces the union.
|
|
32
|
+
*/
|
|
33
|
+
function mapFieldType(field, picklists = "union", typeName) {
|
|
34
|
+
const base = picklistType(field, picklists, typeName) ?? FIELD_TYPE_MAP[field.type] ?? "unknown";
|
|
12
35
|
return field.nillable && base !== "unknown" ? `${base} | null` : base;
|
|
13
36
|
}
|
|
14
|
-
function picklistType(field, picklists) {
|
|
15
|
-
if (picklists
|
|
16
|
-
const values =
|
|
37
|
+
function picklistType(field, picklists, typeName) {
|
|
38
|
+
if (picklists === "string" || field.type !== "picklist" && field.type !== "combobox") return;
|
|
39
|
+
const values = activePicklistValues(field);
|
|
17
40
|
if (values.length === 0) return;
|
|
18
|
-
const
|
|
19
|
-
return field.restrictedPicklist && field.type === "picklist" ?
|
|
41
|
+
const members = picklists !== "union" && typeName !== void 0 ? typeName : values.map((value) => JSON.stringify(value)).join(" | ");
|
|
42
|
+
return field.restrictedPicklist && field.type === "picklist" ? members : `${members} | (string & {})`;
|
|
43
|
+
}
|
|
44
|
+
/** The distinct active values of a picklist, multi-select picklist or combobox, in describe order. */
|
|
45
|
+
function activePicklistValues(field) {
|
|
46
|
+
if (field.type !== "picklist" && field.type !== "multipicklist" && field.type !== "combobox") return [];
|
|
47
|
+
return [...new Set((field.picklistValues ?? []).filter((entry) => entry.active).map((entry) => entry.value))];
|
|
20
48
|
}
|
|
21
49
|
var ADDRESS_TYPE, GEOLOCATION_TYPE, FIELD_TYPE_MAP;
|
|
22
50
|
var init_type_mapper = __esmMin((() => {
|
|
@@ -54,24 +82,151 @@ var init_type_mapper = __esmMin((() => {
|
|
|
54
82
|
};
|
|
55
83
|
}));
|
|
56
84
|
//#endregion
|
|
85
|
+
//#region src/codegen/picklist-types.ts
|
|
86
|
+
function isNamedPicklistMode(mode) {
|
|
87
|
+
return mode === "const" || mode === "enum";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Names the type of every picklist with active values: sObject and field in PascalCase, e.g.
|
|
91
|
+
* `Case.Status` -> `CaseStatus` and `Case.Status__c` -> `CaseStatusCustom`. A name that is in
|
|
92
|
+
* `taken` (the sObjects and other names the file defines) or already used by another picklist gets
|
|
93
|
+
* the suffix `Picklist`; when that is taken too, this throws.
|
|
94
|
+
*/
|
|
95
|
+
function picklistTypeNames(describes, taken) {
|
|
96
|
+
const used = new Map([...taken].map((name) => [name, void 0]));
|
|
97
|
+
const result = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const describe of [...describes].sort((a, b) => compare(a.name, b.name))) {
|
|
99
|
+
const names = /* @__PURE__ */ new Map();
|
|
100
|
+
for (const field of sortedFields(describe).filter((item) => activePicklistValues(item).length > 0)) {
|
|
101
|
+
const base = `${pascalApiName(describe.name, "sobject")}${pascalApiName(field.name, "field")}`;
|
|
102
|
+
if (IDENTIFIER$1.test(base)) {
|
|
103
|
+
const picklist = `${describe.name}.${field.name}`;
|
|
104
|
+
const name = resolveName(base, picklist, used);
|
|
105
|
+
used.set(name, picklist);
|
|
106
|
+
names.set(field.name, name);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (names.size > 0) result.set(describe.name, names);
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
function resolveName(base, picklist, used) {
|
|
114
|
+
const name = used.has(base) ? `${base}${CLASH_SUFFIX}` : base;
|
|
115
|
+
if (used.has(name)) {
|
|
116
|
+
const owner = used.get(name);
|
|
117
|
+
const other = owner === void 0 ? "a type the generated file defines" : `the picklist type for ${owner}`;
|
|
118
|
+
throw new Error(`The picklist type "${name}" for ${picklist} clashes with ${other}; exclude one of the sObjects or use picklists: "union".`);
|
|
119
|
+
}
|
|
120
|
+
return name;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* An API name in PascalCase without underscores. A field's `__c` becomes `Custom`
|
|
124
|
+
* (`Lead_Source__c` -> `LeadSourceCustom`) and an sObject's is dropped (`My_Object__c` ->
|
|
125
|
+
* `MyObject`). Other suffixes are kept: `Foo__pc` -> `FooPc`, `Config__mdt` -> `ConfigMdt`.
|
|
126
|
+
*/
|
|
127
|
+
function pascalApiName(name, kind) {
|
|
128
|
+
const match = /^(.+?)__([a-z]+)$/.exec(name);
|
|
129
|
+
const body = match ? match[1] : name;
|
|
130
|
+
const suffix = match ? match[2] : "";
|
|
131
|
+
const suffixPart = suffix === "c" ? kind === "field" ? "Custom" : "" : capitalize(suffix);
|
|
132
|
+
return `${body.split("_").filter((part) => part.length > 0).map(capitalize).join("")}${suffixPart}`;
|
|
133
|
+
}
|
|
134
|
+
function capitalize(value) {
|
|
135
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The member names for a picklist's values, in the same order. A value that is an identifier is
|
|
139
|
+
* its own name; other values are sanitized (`"Closed Won"` -> `Closed_Won`, `"3rd Party"` ->
|
|
140
|
+
* `_3rd_Party`). When the sanitized name is empty or taken, the value itself is the (quoted) name.
|
|
141
|
+
*/
|
|
142
|
+
function picklistMemberKeys(values, mode) {
|
|
143
|
+
const used = /* @__PURE__ */ new Set();
|
|
144
|
+
const claim = (key) => {
|
|
145
|
+
used.add(key);
|
|
146
|
+
return key;
|
|
147
|
+
};
|
|
148
|
+
const usable = (key) => key.length > 0 && key !== "__proto__" && !used.has(key) && (mode === "const" || !isNumericName(key));
|
|
149
|
+
const own = values.map((value) => IDENTIFIER$1.test(value) && usable(value) ? claim(value) : void 0);
|
|
150
|
+
return values.map((value, index) => {
|
|
151
|
+
const ownKey = own[index];
|
|
152
|
+
if (ownKey !== void 0) return ownKey;
|
|
153
|
+
const sanitized = sanitizeKey(value);
|
|
154
|
+
if (usable(sanitized)) return claim(sanitized);
|
|
155
|
+
if (usable(value)) return claim(value);
|
|
156
|
+
let counter = 2;
|
|
157
|
+
while (!usable(`${sanitized || "_"}_${counter}`)) counter++;
|
|
158
|
+
return claim(`${sanitized || "_"}_${counter}`);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function sanitizeKey(value) {
|
|
162
|
+
const key = value.normalize("NFKD").replace(/\p{M}/gu, "").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
163
|
+
return /^[0-9]/.test(key) ? `_${key}` : key;
|
|
164
|
+
}
|
|
165
|
+
/** Names TypeScript rejects as enum members because they are numeric, e.g. `"1"` or `"-1"`. */
|
|
166
|
+
function isNumericName(key) {
|
|
167
|
+
const number = Number(key);
|
|
168
|
+
return Number.isFinite(number) && String(number) === key;
|
|
169
|
+
}
|
|
170
|
+
/** The named type declarations for one sObject's picklists, in field order; `""` when there are none. */
|
|
171
|
+
function picklistDeclarations(describe, names, mode) {
|
|
172
|
+
if (!names) return "";
|
|
173
|
+
return sortedFields(describe).flatMap((field) => {
|
|
174
|
+
const name = names.get(field.name);
|
|
175
|
+
return name === void 0 ? [] : [declaration(describe.name, field, name, mode)];
|
|
176
|
+
}).join("\n\n");
|
|
177
|
+
}
|
|
178
|
+
function declaration(sobject, field, name, mode) {
|
|
179
|
+
const values = activePicklistValues(field);
|
|
180
|
+
const keys = picklistMemberKeys(values, mode);
|
|
181
|
+
const doc = `/** Active values of ${escapeComment(`${sobject}.${field.name}`)} (${escapeComment(field.type)}). */`;
|
|
182
|
+
if (mode === "enum") {
|
|
183
|
+
const members = values.map((value, index) => `\t${propertyKey(keys[index])} = ${JSON.stringify(value)},`);
|
|
184
|
+
return [
|
|
185
|
+
doc,
|
|
186
|
+
`export enum ${name} {`,
|
|
187
|
+
...members,
|
|
188
|
+
"}"
|
|
189
|
+
].join("\n");
|
|
190
|
+
}
|
|
191
|
+
const members = values.map((value, index) => `\t${propertyKey(keys[index])}: ${JSON.stringify(value)},`);
|
|
192
|
+
return [
|
|
193
|
+
doc,
|
|
194
|
+
`export const ${name} = {`,
|
|
195
|
+
...members,
|
|
196
|
+
"} as const;",
|
|
197
|
+
`export type ${name} = (typeof ${name})[keyof typeof ${name}];`
|
|
198
|
+
].join("\n");
|
|
199
|
+
}
|
|
200
|
+
var CLASH_SUFFIX;
|
|
201
|
+
var init_picklist_types = __esmMin((() => {
|
|
202
|
+
init_emit();
|
|
203
|
+
init_type_mapper();
|
|
204
|
+
CLASH_SUFFIX = "Picklist";
|
|
205
|
+
}));
|
|
206
|
+
//#endregion
|
|
57
207
|
//#region src/codegen/generator.ts
|
|
58
208
|
/**
|
|
59
209
|
* Generates the TypeScript source for a set of sObject describes: a read interface, create
|
|
60
|
-
* and update input types per sObject, and the `SObjectRegistry` that ties them together.
|
|
210
|
+
* and update input types per sObject, and the `SObjectRegistry` that ties them together. With
|
|
211
|
+
* picklist mode `"const"` or `"enum"`, each picklist also gets a named type before its sObject.
|
|
61
212
|
* The output is deterministic: sObjects are sorted by name and fields by name (`Id` first).
|
|
62
213
|
*/
|
|
63
214
|
function generateSource(describes, options = {}) {
|
|
64
215
|
const sorted = [...describes].sort((a, b) => compare(a.name, b.name));
|
|
65
|
-
assertGeneratableNames(sorted);
|
|
216
|
+
const definedNames = assertGeneratableNames(sorted);
|
|
66
217
|
const names = new Set(sorted.map((describe) => describe.name));
|
|
218
|
+
const picklists = options.picklists ?? "union";
|
|
219
|
+
const picklistTypes = isNamedPicklistMode(picklists) ? picklistTypeNames(sorted, definedNames) : void 0;
|
|
67
220
|
const sections = [imports(sorted, options.importSource ?? "@cerios/salesforce-sobjectly")];
|
|
68
221
|
const objectHashes = [];
|
|
69
222
|
for (const describe of sorted) {
|
|
223
|
+
const typeNames = picklistTypes?.get(describe.name);
|
|
70
224
|
const objectSections = [
|
|
71
|
-
|
|
225
|
+
isNamedPicklistMode(picklists) ? picklistDeclarations(describe, typeNames, picklists) : "",
|
|
226
|
+
readInterface(describe, picklists, typeNames),
|
|
72
227
|
inputType(describe, "CreateInput", "createable", lookup(options.excludeCreateFields, describe.name)),
|
|
73
228
|
inputType(describe, "UpdateInput", "updateable", lookup(options.excludeUpdateFields, describe.name))
|
|
74
|
-
];
|
|
229
|
+
].filter((section) => section.length > 0);
|
|
75
230
|
sections.push(...objectSections);
|
|
76
231
|
const fingerprint = [
|
|
77
232
|
...objectSections,
|
|
@@ -86,7 +241,10 @@ function generateSource(describes, options = {}) {
|
|
|
86
241
|
const body = sections.filter((section) => section.length > 0).join("\n\n");
|
|
87
242
|
return `${header(sha256(body), objectHashes)}\n\n${body}\n`;
|
|
88
243
|
}
|
|
89
|
-
/**
|
|
244
|
+
/**
|
|
245
|
+
* Fails with a clear message for sObject names the generated TypeScript can't represent. Returns
|
|
246
|
+
* every name the file defines apart from picklist types, so those can avoid them.
|
|
247
|
+
*/
|
|
90
248
|
function assertGeneratableNames(describes) {
|
|
91
249
|
const seen = /* @__PURE__ */ new Map();
|
|
92
250
|
const generated = new Set(describes.flatMap((describe) => [`${describe.name}CreateInput`, `${describe.name}UpdateInput`]));
|
|
@@ -97,6 +255,11 @@ function assertGeneratableNames(describes) {
|
|
|
97
255
|
if (previous !== void 0) throw new Error(`sObjects "${previous}" and "${name}" differ only in case; list each sObject once.`);
|
|
98
256
|
seen.set(name.toLowerCase(), name);
|
|
99
257
|
}
|
|
258
|
+
return /* @__PURE__ */ new Set([
|
|
259
|
+
...RESERVED_TYPE_NAMES,
|
|
260
|
+
...generated,
|
|
261
|
+
...describes.map((describe) => describe.name)
|
|
262
|
+
]);
|
|
100
263
|
}
|
|
101
264
|
/** Looks up a per-sObject option case-insensitively (sObject names are case-insensitive in Salesforce). */
|
|
102
265
|
function lookup(map, name) {
|
|
@@ -141,12 +304,11 @@ function imports(describes, importSource) {
|
|
|
141
304
|
if (fields.some((field) => field.type === "location")) used.push(GEOLOCATION_TYPE);
|
|
142
305
|
return used.length > 0 ? `import type { ${used.join(", ")} } from ${JSON.stringify(importSource)};` : "";
|
|
143
306
|
}
|
|
144
|
-
function
|
|
145
|
-
return [...describe.fields].sort((a, b) => a.name === "Id" ? -1 : b.name === "Id" ? 1 : compare(a.name, b.name));
|
|
146
|
-
}
|
|
147
|
-
function readInterface(describe, picklists) {
|
|
307
|
+
function readInterface(describe, picklists, typeNames) {
|
|
148
308
|
const lines = sortedFields(describe).map((field) => {
|
|
149
|
-
|
|
309
|
+
const comment = `\t/** ${escapeComment(field.label)} (${escapeComment(field.type)}) */`;
|
|
310
|
+
const type = mapFieldType(field, picklists, typeNames?.get(field.name));
|
|
311
|
+
return `${comment}\n\t${propertyKey(field.name)}: ${type};`;
|
|
150
312
|
});
|
|
151
313
|
return `${describe.label ? `/** ${escapeComment(describe.label)} */\n` : ""}export interface ${describe.name} {\n${lines.join("\n")}\n}`;
|
|
152
314
|
}
|
|
@@ -233,10 +395,6 @@ function recordTypeConstants(describes) {
|
|
|
233
395
|
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(", ")}],`);
|
|
234
396
|
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");
|
|
235
397
|
}
|
|
236
|
-
function activePicklistValues(field) {
|
|
237
|
-
if (field.type !== "picklist" && field.type !== "multipicklist" && field.type !== "combobox") return [];
|
|
238
|
-
return [...new Set((field.picklistValues ?? []).filter((entry) => entry.active).map((entry) => entry.value))];
|
|
239
|
-
}
|
|
240
398
|
function unionOrNever(values) {
|
|
241
399
|
return values.length > 0 ? values.map((value) => JSON.stringify(value)).join(" | ") : "never";
|
|
242
400
|
}
|
|
@@ -259,17 +417,10 @@ function relationshipMap(entries) {
|
|
|
259
417
|
function keyUnion(names) {
|
|
260
418
|
return names.map((name) => JSON.stringify(name)).join(" | ");
|
|
261
419
|
}
|
|
262
|
-
|
|
263
|
-
return IDENTIFIER$1.test(name) ? name : JSON.stringify(name);
|
|
264
|
-
}
|
|
265
|
-
function escapeComment(value) {
|
|
266
|
-
return String(value ?? "").replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
267
|
-
}
|
|
268
|
-
function compare(a, b) {
|
|
269
|
-
return a < b ? -1 : a > b ? 1 : 0;
|
|
270
|
-
}
|
|
271
|
-
var FIELD_KINDS, IDENTIFIER$1, RESERVED_TYPE_NAMES, CONTENT_HASH_PREFIX, OBJECT_HASHES_PREFIX, OBJECT_HASH_LENGTH;
|
|
420
|
+
var FIELD_KINDS, RESERVED_TYPE_NAMES, CONTENT_HASH_PREFIX, OBJECT_HASHES_PREFIX, OBJECT_HASH_LENGTH;
|
|
272
421
|
var init_generator = __esmMin((() => {
|
|
422
|
+
init_emit();
|
|
423
|
+
init_picklist_types();
|
|
273
424
|
init_type_mapper();
|
|
274
425
|
FIELD_KINDS = /* @__PURE__ */ new Set([
|
|
275
426
|
"date",
|
|
@@ -277,7 +428,6 @@ var init_generator = __esmMin((() => {
|
|
|
277
428
|
"time",
|
|
278
429
|
"multipicklist"
|
|
279
430
|
]);
|
|
280
|
-
IDENTIFIER$1 = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
281
431
|
RESERVED_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
282
432
|
"Record",
|
|
283
433
|
"Pick",
|
|
@@ -397,7 +547,12 @@ var init_validate_config = __esmMin((() => {
|
|
|
397
547
|
],
|
|
398
548
|
sfCli: ["targetOrg"]
|
|
399
549
|
};
|
|
400
|
-
PICKLIST_MODES = [
|
|
550
|
+
PICKLIST_MODES = [
|
|
551
|
+
"union",
|
|
552
|
+
"string",
|
|
553
|
+
"const",
|
|
554
|
+
"enum"
|
|
555
|
+
];
|
|
401
556
|
IDENTIFIER = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
402
557
|
VALIDATORS = {
|
|
403
558
|
$schema: (value, { problem }) => {
|
|
@@ -417,7 +572,7 @@ var init_validate_config = __esmMin((() => {
|
|
|
417
572
|
excludeCreateFields: (value, context) => validateFieldMap("excludeCreateFields", value, context),
|
|
418
573
|
excludeUpdateFields: (value, context) => validateFieldMap("excludeUpdateFields", value, context),
|
|
419
574
|
picklists: (value, { problem }) => {
|
|
420
|
-
if (!PICKLIST_MODES.includes(value)) problem(`picklists: must be
|
|
575
|
+
if (!PICKLIST_MODES.includes(value)) problem(`picklists: must be one of ${PICKLIST_MODES.join(", ")}, got ${show(value)}.`);
|
|
421
576
|
},
|
|
422
577
|
constants: (value, { problem }) => {
|
|
423
578
|
if (typeof value !== "boolean") problem(`constants: must be true or false, got ${show(value)}.`);
|
|
@@ -759,13 +914,24 @@ var init_init = __esmMin((() => {
|
|
|
759
914
|
label: "JWT bearer (certificate-based, runs as a user)"
|
|
760
915
|
}
|
|
761
916
|
];
|
|
762
|
-
PICKLIST_CHOICES = [
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
917
|
+
PICKLIST_CHOICES = [
|
|
918
|
+
{
|
|
919
|
+
value: "union",
|
|
920
|
+
label: "Union of values, e.g. \"New\" | \"Closed\" (type-safe)"
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
value: "string",
|
|
924
|
+
label: "Plain string"
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
value: "const",
|
|
928
|
+
label: "Union plus a named constant per picklist, e.g. CaseStatus.Closed"
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
value: "enum",
|
|
932
|
+
label: "TypeScript enum per picklist (restricted picklists only accept enum members)"
|
|
933
|
+
}
|
|
934
|
+
];
|
|
769
935
|
FORMAT_CHOICES = [{
|
|
770
936
|
value: "ts",
|
|
771
937
|
label: "TypeScript (sobjectly.config.ts, type-checked with defineConfig)"
|
|
@@ -1105,6 +1271,6 @@ var init_codegen = __esmMin((() => {
|
|
|
1105
1271
|
};
|
|
1106
1272
|
}));
|
|
1107
1273
|
//#endregion
|
|
1108
|
-
export {
|
|
1274
|
+
export { mapFieldType as A, init_validate_config as C, readGeneratedHashes as D, init_generator as E, FIELD_TYPE_MAP as O, PICKLIST_MODES as S, generateSource as T, defineConfig as _, init_prompter as a, CONFIG_OPTIONS as b, init_init as c, runInit as d, CONFIG_FILE_NAMES as f, loadConfig as g, init_load_config as h, resolveAuth as i, init_type_mapper as k, parseSObjects as l, findConfigFiles as m, generate as n, readlinePrompter as o, findConfigFile as p, init_codegen as r, AUTH_ENV_VARS as s, checkGenerated as t, renderConfig as u, init_config as v, validateConfig as w, CodegenConfigError as x, AUTH_OPTIONS as y };
|
|
1109
1275
|
|
|
1110
|
-
//# sourceMappingURL=codegen-
|
|
1276
|
+
//# sourceMappingURL=codegen-C6MEYiWo.mjs.map
|