@nyrra/prismantix-cli 0.0.4-next.23 → 0.0.4-next.25

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.
@@ -1,8 +1,14 @@
1
1
  import { arrayField, isRecord } from "./utils.js";
2
+ const baseTypeFields = ["baseType", "dataType", "type"];
3
+ const dataTypeFields = ["dataType", "type"];
4
+ const interfaceTypeFields = ["type", "dataType", "fieldType"];
2
5
  export function parseFoundryV2Export(input, diagnostics) {
3
6
  if (!isRecord(input)) {
4
7
  throw new Error("Expected a JSON object.");
5
8
  }
9
+ if (isFoundryFullMetadataExport(input)) {
10
+ return parseFoundryFullMetadataExport(input, diagnostics);
11
+ }
6
12
  const version = typeof input.version === "number" ? input.version : 0;
7
13
  addVersionDiagnostic(version, input.version, diagnostics);
8
14
  return {
@@ -15,6 +21,520 @@ export function parseFoundryV2Export(input, diagnostics) {
15
21
  version,
16
22
  };
17
23
  }
24
+ function isFoundryFullMetadataExport(input) {
25
+ const objectTypes = input.objectTypes;
26
+ return (isRecord(objectTypes) &&
27
+ Object.values(objectTypes).some((value) => isRecord(value) && isRecord(value.objectType)));
28
+ }
29
+ function parseFoundryFullMetadataExport(input, diagnostics) {
30
+ const objectTypes = recordField(input, "objectTypes");
31
+ return {
32
+ actionTypes: recordValues(input, "actionTypes").map(fullMetadataActionType),
33
+ interfaces: recordValues(input, "interfaceTypes").map(fullMetadataInterface),
34
+ objectTypes: Object.values(objectTypes).map(fullMetadataObjectType),
35
+ relations: fullMetadataRelations(objectTypes, diagnostics),
36
+ sharedProperties: recordValues(input, "sharedPropertyTypes").map(fullMetadataSharedProperty),
37
+ typeGroups: arrayField(input, "typeGroups"),
38
+ version: 2,
39
+ };
40
+ }
41
+ function fullMetadataObjectType(value) {
42
+ const wrapper = isRecord(value) ? value : {};
43
+ const objectType = isRecord(wrapper.objectType)
44
+ ? wrapper.objectType
45
+ : wrapper;
46
+ return {
47
+ aliases: stringArray(objectType.aliases),
48
+ apiName: stringField(objectType, "apiName"),
49
+ datasources: arrayField(objectType, "datasources"),
50
+ displayMetadata: fullMetadataDisplayMetadata(objectType),
51
+ interfaces: fullMetadataObjectInterfaces(wrapper),
52
+ interfaceImplementations: fullMetadataObjectInterfaceImplementations(wrapper),
53
+ primaryKeys: fullMetadataPrimaryKeys(objectType),
54
+ properties: recordEntries(objectType, "properties").map(([key, property]) => fullMetadataProperty(key, property)),
55
+ rid: stringField(objectType, "rid"),
56
+ status: fullMetadataStatus(objectType.status),
57
+ titlePropertyId: fullMetadataTitleProperty(objectType),
58
+ typeGroups: stringArray(objectType.typeGroups),
59
+ };
60
+ }
61
+ function fullMetadataPrimaryKeys(objectType) {
62
+ const primaryKey = stringField(objectType, "primaryKey");
63
+ return primaryKey ? [primaryKey] : stringArray(objectType.primaryKeys);
64
+ }
65
+ function fullMetadataTitleProperty(objectType) {
66
+ return firstStringField(objectType, ["titleProperty", "titlePropertyId"]);
67
+ }
68
+ function fullMetadataObjectInterfaces(wrapper) {
69
+ const implementsInterfaces = stringArray(wrapper.implementsInterfaces);
70
+ if (implementsInterfaces.length > 0) {
71
+ return implementsInterfaces;
72
+ }
73
+ const implementsInterfaces2 = wrapper.implementsInterfaces2;
74
+ return isRecord(implementsInterfaces2)
75
+ ? Object.keys(implementsInterfaces2)
76
+ : [];
77
+ }
78
+ function fullMetadataObjectInterfaceImplementations(wrapper) {
79
+ const implementsInterfaces2 = wrapper.implementsInterfaces2;
80
+ if (!isRecord(implementsInterfaces2)) {
81
+ return [];
82
+ }
83
+ return Object.entries(implementsInterfaces2).map(([interfaceApiName, implementation]) => ({
84
+ interfaceApiName: fullMetadataImplementationApiName(interfaceApiName, implementation),
85
+ propertyMappings: fullMetadataObjectInterfacePropertyMappings(implementation),
86
+ }));
87
+ }
88
+ function fullMetadataImplementationApiName(interfaceApiName, implementation) {
89
+ const record = isRecord(implementation) ? implementation : {};
90
+ return stringField(record, "apiName") ?? interfaceApiName;
91
+ }
92
+ function fullMetadataObjectInterfacePropertyMappings(implementation) {
93
+ const record = isRecord(implementation) ? implementation : {};
94
+ const propertiesV2 = recordField(record, "propertiesV2");
95
+ const v2Entries = Object.entries(propertiesV2).flatMap(([interfacePropertyApiName, mapping]) => {
96
+ const objectPropertyApiName = fullMetadataPropertyMappingTarget(mapping);
97
+ return objectPropertyApiName
98
+ ? [{ interfacePropertyApiName, objectPropertyApiName }]
99
+ : [];
100
+ });
101
+ if (v2Entries.length > 0) {
102
+ return v2Entries;
103
+ }
104
+ return recordEntries(record, "properties").flatMap(([interfacePropertyApiName, objectPropertyApiName]) => typeof objectPropertyApiName === "string"
105
+ ? [{ interfacePropertyApiName, objectPropertyApiName }]
106
+ : []);
107
+ }
108
+ function fullMetadataPropertyMappingTarget(mapping) {
109
+ if (typeof mapping === "string") {
110
+ return mapping;
111
+ }
112
+ const record = isRecord(mapping) ? mapping : {};
113
+ return (stringField(record, "propertyApiName") ??
114
+ stringField(record, "propertyTypeRid"));
115
+ }
116
+ function fullMetadataProperty(apiName, value) {
117
+ const property = isRecord(value) ? value : {};
118
+ return {
119
+ apiName: stringFieldWithFallback(property, "apiName", apiName),
120
+ baseFormatter: property.baseFormatter,
121
+ baseType: fullMetadataBaseType(firstPresentValue(property, baseTypeFields)),
122
+ dataConstraints: dataConstraints(property),
123
+ displayMetadata: fullMetadataDisplayMetadata(property),
124
+ id: stringFieldWithFallback(property, "id", apiName),
125
+ indexedForSearch: booleanField(property, "indexedForSearch"),
126
+ renderHints: renderHints(property),
127
+ rid: stringField(property, "rid"),
128
+ source: recordOrUndefined(property.source),
129
+ status: fullMetadataStatus(property.status),
130
+ typeClasses: arrayField(property, "typeClasses"),
131
+ valueType: fullMetadataValueType(property),
132
+ };
133
+ }
134
+ function fullMetadataActionType(value) {
135
+ const action = isRecord(value) ? value : {};
136
+ const operations = arrayField(action, "operations").map(fullMetadataActionOperation);
137
+ return {
138
+ actionTypeLogic: {
139
+ logic: {
140
+ rules: operations.map((operation) => ({
141
+ objectTypeApiName: operation.objectTypeApiName,
142
+ type: operation.type,
143
+ })),
144
+ },
145
+ },
146
+ metadata: {
147
+ apiName: stringField(action, "apiName"),
148
+ displayMetadata: fullMetadataDisplayMetadata(action),
149
+ formContentInOrder: recordEntries(action, "parameters").map(([id, parameter]) => ({
150
+ parameter: fullMetadataActionParameter(id, parameter),
151
+ type: "parameter",
152
+ })),
153
+ rid: stringField(action, "rid"),
154
+ status: fullMetadataStatus(action.status),
155
+ },
156
+ operations,
157
+ };
158
+ }
159
+ function fullMetadataActionOperation(value) {
160
+ const operation = isRecord(value) ? value : {};
161
+ return {
162
+ objectTypeApiName: stringField(operation, "objectTypeApiName"),
163
+ type: stringField(operation, "type"),
164
+ };
165
+ }
166
+ function fullMetadataActionParameter(id, value) {
167
+ const parameter = isRecord(value) ? value : {};
168
+ return {
169
+ displayMetadata: fullMetadataDisplayMetadata(parameter),
170
+ id,
171
+ required: booleanField(parameter, "required"),
172
+ type: fullMetadataBaseType(firstPresentValue(parameter, dataTypeFields)),
173
+ };
174
+ }
175
+ function fullMetadataInterface(value) {
176
+ const interfaceType = isRecord(value) ? value : {};
177
+ return {
178
+ apiName: stringField(interfaceType, "apiName"),
179
+ displayMetadata: fullMetadataDisplayMetadata(interfaceType),
180
+ extendsInterfaces: stringArray(interfaceType.extendsInterfaces),
181
+ links: recordOrArrayEntries(interfaceType.links).map(([key, link]) => fullMetadataInterfaceLink(key, link)),
182
+ properties: recordOrArrayEntries(interfaceType.properties).map(([key, property]) => fullMetadataInterfaceProperty(key, property)),
183
+ rid: stringField(interfaceType, "rid"),
184
+ searchable: booleanField(interfaceType, "searchable"),
185
+ status: fullMetadataStatus(interfaceType.status),
186
+ };
187
+ }
188
+ function fullMetadataInterfaceProperty(apiName, value) {
189
+ const property = isRecord(value) ? value : {};
190
+ return {
191
+ apiName: stringFieldWithFallback(property, "apiName", apiName),
192
+ displayName: stringField(property, "displayName"),
193
+ isSharedProperty: booleanField(property, "isSharedProperty"),
194
+ required: firstBooleanField(property, [
195
+ "required",
196
+ "requireImplementation",
197
+ ]),
198
+ sharedPropertyRid: stringField(property, "sharedPropertyRid"),
199
+ type: fullMetadataBaseType(firstPresentValue(property, interfaceTypeFields)),
200
+ };
201
+ }
202
+ function fullMetadataInterfaceLink(apiName, value) {
203
+ const link = isRecord(value) ? value : {};
204
+ const linkedEntity = isRecord(link.linkedEntityApiName)
205
+ ? link.linkedEntityApiName
206
+ : {};
207
+ return {
208
+ apiName: stringFieldWithFallback(link, "apiName", apiName),
209
+ cardinality: stringField(link, "cardinality"),
210
+ description: nullableStringField(link, "description") ?? undefined,
211
+ displayName: stringField(link, "displayName"),
212
+ linkedEntityApiName: stringField(linkedEntity, "apiName"),
213
+ linkedEntityType: stringField(linkedEntity, "type"),
214
+ required: booleanField(link, "required"),
215
+ rid: stringField(link, "rid"),
216
+ };
217
+ }
218
+ function fullMetadataSharedProperty(value) {
219
+ const property = isRecord(value) ? value : {};
220
+ return {
221
+ aliases: stringArray(property.aliases),
222
+ apiName: stringField(property, "apiName"),
223
+ baseType: fullMetadataBaseType(firstPresentValue(property, baseTypeFields)),
224
+ dataConstraints: dataConstraints(property),
225
+ displayMetadata: fullMetadataDisplayMetadata(property),
226
+ indexedForSearch: booleanField(property, "indexedForSearch"),
227
+ renderHints: renderHints(property),
228
+ rid: stringField(property, "rid"),
229
+ valueType: fullMetadataValueType(property),
230
+ };
231
+ }
232
+ function fullMetadataRelations(objectTypes, diagnostics) {
233
+ const groups = fullMetadataLinkGroups(objectTypes);
234
+ return [...groups.entries()].flatMap(([relationRid, links], relationIndex) => fullMetadataRelation(relationRid, links, relationIndex, diagnostics));
235
+ }
236
+ function fullMetadataLinkGroups(objectTypes) {
237
+ const groups = new Map();
238
+ for (const value of Object.values(objectTypes)) {
239
+ addFullMetadataObjectLinks(groups, value);
240
+ }
241
+ return groups;
242
+ }
243
+ function addFullMetadataObjectLinks(groups, value) {
244
+ const wrapper = isRecord(value) ? value : {};
245
+ const context = fullMetadataLinkContext(wrapper);
246
+ if (!context) {
247
+ return;
248
+ }
249
+ for (const link of arrayField(wrapper, "linkTypes")) {
250
+ addFullMetadataLink(groups, context, link);
251
+ }
252
+ }
253
+ function addFullMetadataLink(groups, context, value) {
254
+ const linkRecord = isRecord(value) ? value : {};
255
+ const relationRid = fullMetadataRelationRid(context.sourceApiName, linkRecord);
256
+ const group = groups.get(relationRid) ?? [];
257
+ group.push({ link: linkRecord, ...context });
258
+ groups.set(relationRid, group);
259
+ }
260
+ function fullMetadataLinkContext(wrapper) {
261
+ const objectType = fullMetadataWrappedObjectType(wrapper);
262
+ const sourceApiName = stringField(objectType, "apiName");
263
+ const sourceRid = stringField(objectType, "rid");
264
+ return sourceApiName && sourceRid ? { sourceApiName, sourceRid } : undefined;
265
+ }
266
+ function fullMetadataRelationRid(sourceApiName, link) {
267
+ return (stringField(link, "linkTypeRid") ??
268
+ `${sourceApiName}:${stringFieldWithFallback(link, "apiName", "link")}`);
269
+ }
270
+ function fullMetadataRelation(relationRid, links, relationIndex, diagnostics) {
271
+ if (links.length !== 2) {
272
+ diagnostics.push({
273
+ code: "skipped.fullMetadataLinkGroup",
274
+ message: `Foundry full-metadata link group ${relationRid} has ${links.length} sides; expected 2.`,
275
+ path: `$.objectTypes.*.linkTypes[${relationIndex}]`,
276
+ severity: "warning",
277
+ });
278
+ return [];
279
+ }
280
+ const foreignKeySide = links.find((link) => Boolean(stringField(link.link, "foreignKeyPropertyApiName")));
281
+ if (foreignKeySide) {
282
+ return fullMetadataOneToManyRelation(relationRid, links, foreignKeySide);
283
+ }
284
+ return [fullMetadataManyToManyRelation(relationRid, linkPair(links))];
285
+ }
286
+ function fullMetadataManyToManyRelation(relationRid, [a, b]) {
287
+ return {
288
+ definition: {
289
+ manyToMany: {
290
+ objectTypeAToBLinkMetadata: fullMetadataLinkMetadata(a.link),
291
+ objectTypeBToALinkMetadata: fullMetadataLinkMetadata(b.link),
292
+ objectTypeRidA: a.sourceRid,
293
+ objectTypeRidB: b.sourceRid,
294
+ },
295
+ type: "manyToMany",
296
+ },
297
+ id: relationRid,
298
+ rid: relationRid,
299
+ status: fullMetadataStatus(firstPresentValueFromList([a.link, b.link], "status")),
300
+ };
301
+ }
302
+ function fullMetadataOneToManyRelation(relationRid, links, foreignKeySide) {
303
+ const oneSide = links.find((link) => link !== foreignKeySide);
304
+ if (!oneSide) {
305
+ return [];
306
+ }
307
+ return [
308
+ {
309
+ definition: {
310
+ oneToMany: {
311
+ cardinalityHint: stringField(oneSide.link, "cardinality") === "ONE"
312
+ ? "ONE_TO_ONE"
313
+ : "ONE_TO_MANY",
314
+ manySideForeignKeyPropertyId: stringField(foreignKeySide.link, "foreignKeyPropertyApiName"),
315
+ manyToOneLinkMetadata: fullMetadataLinkMetadata(foreignKeySide.link),
316
+ objectTypeRidManySide: foreignKeySide.sourceRid,
317
+ objectTypeRidOneSide: oneSide.sourceRid,
318
+ oneToManyLinkMetadata: fullMetadataLinkMetadata(oneSide.link),
319
+ },
320
+ type: "oneToMany",
321
+ },
322
+ id: relationRid,
323
+ rid: relationRid,
324
+ status: fullMetadataStatus(foreignKeySide.link.status ?? oneSide.link.status),
325
+ },
326
+ ];
327
+ }
328
+ function fullMetadataLinkMetadata(link) {
329
+ return {
330
+ apiName: stringField(link, "apiName"),
331
+ displayMetadata: fullMetadataDisplayMetadata(link),
332
+ typeClasses: arrayField(link, "typeClasses"),
333
+ };
334
+ }
335
+ function fullMetadataWrappedObjectType(value) {
336
+ const wrapper = isRecord(value) ? value : {};
337
+ return isRecord(wrapper.objectType) ? wrapper.objectType : wrapper;
338
+ }
339
+ function fullMetadataBaseType(value) {
340
+ const record = recordOrUndefined(value);
341
+ return record ? fullMetadataBaseTypeFromRecord(record) : undefined;
342
+ }
343
+ function fullMetadataBaseTypeFromRecord(value) {
344
+ const type = stringField(value, "type");
345
+ return type
346
+ ? typedFullMetadataBaseType(value, type)
347
+ : value;
348
+ }
349
+ function typedFullMetadataBaseType(value, type) {
350
+ const normalizedType = normalizeFullMetadataType(type);
351
+ return {
352
+ ...value,
353
+ ...fullMetadataBaseTypeExtras(value, normalizedType),
354
+ type: normalizedType,
355
+ };
356
+ }
357
+ function fullMetadataBaseTypeExtras(value, type) {
358
+ const extras = {
359
+ ARRAY: () => ({ subType: fullMetadataBaseType(value.subType) }),
360
+ STRUCT: () => ({
361
+ structFields: recordOrArrayValues(value.fields).map((field) => fullMetadataStructField(field)),
362
+ }),
363
+ };
364
+ return extras[type]?.() ?? {};
365
+ }
366
+ function fullMetadataStructField(value) {
367
+ const field = isRecord(value) ? value : {};
368
+ return {
369
+ apiName: stringField(field, "apiName") ?? stringField(field, "name"),
370
+ displayMetadata: fullMetadataDisplayMetadata(field),
371
+ fieldType: fullMetadataBaseType(field.fieldType ?? field.dataType),
372
+ };
373
+ }
374
+ function normalizeFullMetadataType(type) {
375
+ const typeMap = {
376
+ array: "ARRAY",
377
+ attachment: "ATTACHMENT",
378
+ boolean: "BOOLEAN",
379
+ date: "DATE",
380
+ double: "DOUBLE",
381
+ geohash: "GEOHASH",
382
+ geopoint: "GEOHASH",
383
+ geoshape: "GEOSHAPE",
384
+ integer: "INTEGER",
385
+ long: "LONG",
386
+ marking: "MARKING",
387
+ mediaReference: "MEDIA_REFERENCE",
388
+ string: "STRING",
389
+ struct: "STRUCT",
390
+ timestamp: "TIMESTAMP",
391
+ vector: "VECTOR",
392
+ };
393
+ return typeMap[type] ?? type;
394
+ }
395
+ function fullMetadataStatus(value) {
396
+ const type = fullMetadataStatusType(value);
397
+ return type
398
+ ? { ...fullMetadataStatusRecord(value), type: type.toLowerCase() }
399
+ : undefined;
400
+ }
401
+ function fullMetadataStatusRecord(value) {
402
+ return isRecord(value) ? value : {};
403
+ }
404
+ function fullMetadataStatusType(value) {
405
+ return typeof value === "string"
406
+ ? nonEmptyString(value)
407
+ : stringField(fullMetadataStatusRecord(value), "type");
408
+ }
409
+ function fullMetadataDisplayMetadata(record) {
410
+ const nested = recordOrUndefined(record.displayMetadata);
411
+ return nested ? nested : displayMetadataFromTopLevelFields(record);
412
+ }
413
+ function displayMetadataFromTopLevelFields(record) {
414
+ const displayMetadata = {
415
+ description: nullableStringField(record, "description"),
416
+ displayName: nullableStringField(record, "displayName"),
417
+ groupDisplayName: nullableStringField(record, "groupDisplayName"),
418
+ icon: definedValue(record.icon),
419
+ pluralDisplayName: nullableStringField(record, "pluralDisplayName"),
420
+ visibility: nullableStringField(record, "visibility"),
421
+ };
422
+ const compact = compactRecord(displayMetadata);
423
+ return Object.keys(compact).length > 0
424
+ ? compact
425
+ : undefined;
426
+ }
427
+ function linkPair(links) {
428
+ return [links[0], links[1]];
429
+ }
430
+ function fullMetadataValueType(record) {
431
+ const explicit = record.valueType;
432
+ return explicit === undefined ? valueTypeReference(record) : explicit;
433
+ }
434
+ function firstPresentValue(record, keys) {
435
+ for (const key of keys) {
436
+ const value = record[key];
437
+ if (value !== undefined) {
438
+ return value;
439
+ }
440
+ }
441
+ return undefined;
442
+ }
443
+ function firstPresentValueFromList(records, key) {
444
+ for (const record of records) {
445
+ const value = record[key];
446
+ if (value !== undefined) {
447
+ return value;
448
+ }
449
+ }
450
+ return undefined;
451
+ }
452
+ function firstStringField(record, keys) {
453
+ for (const key of keys) {
454
+ const value = stringField(record, key);
455
+ if (value) {
456
+ return value;
457
+ }
458
+ }
459
+ return undefined;
460
+ }
461
+ function firstBooleanField(record, keys) {
462
+ for (const key of keys) {
463
+ const value = booleanField(record, key);
464
+ if (value !== undefined) {
465
+ return value;
466
+ }
467
+ }
468
+ return undefined;
469
+ }
470
+ function stringFieldWithFallback(record, key, fallback) {
471
+ return stringField(record, key) ?? fallback;
472
+ }
473
+ function recordOrUndefined(value) {
474
+ return isRecord(value) ? value : undefined;
475
+ }
476
+ function nonEmptyString(value) {
477
+ return value === "" ? undefined : value;
478
+ }
479
+ function nullableStringField(record, key) {
480
+ const value = record[key];
481
+ return typeof value === "string" || value === null ? value : undefined;
482
+ }
483
+ function definedValue(value) {
484
+ return value === undefined ? undefined : value;
485
+ }
486
+ function compactRecord(record) {
487
+ return Object.fromEntries(Object.entries(record).filter((entry) => entry[1] !== undefined));
488
+ }
489
+ function dataConstraints(record) {
490
+ return isRecord(record.dataConstraints) ? record.dataConstraints : undefined;
491
+ }
492
+ function valueTypeReference(record) {
493
+ const valueTypeApiName = stringField(record, "valueTypeApiName");
494
+ return valueTypeApiName ? { apiName: valueTypeApiName } : undefined;
495
+ }
496
+ function renderHints(record) {
497
+ const explicit = stringArray(record.renderHints);
498
+ if (explicit.length > 0) {
499
+ return explicit;
500
+ }
501
+ return arrayField(record, "typeClasses").flatMap((typeClass) => typeClass.kind === "render_hint" && typeClass.name ? [typeClass.name] : []);
502
+ }
503
+ function recordField(record, key) {
504
+ const value = record[key];
505
+ return isRecord(value) ? value : {};
506
+ }
507
+ function recordValues(record, key) {
508
+ return Object.values(recordField(record, key));
509
+ }
510
+ function recordEntries(record, key) {
511
+ return Object.entries(recordField(record, key));
512
+ }
513
+ function recordOrArrayValues(value) {
514
+ if (Array.isArray(value)) {
515
+ return value;
516
+ }
517
+ return isRecord(value) ? Object.values(value) : [];
518
+ }
519
+ function recordOrArrayEntries(value) {
520
+ if (Array.isArray(value)) {
521
+ return value.map((item, index) => [String(index), item]);
522
+ }
523
+ return isRecord(value) ? Object.entries(value) : [];
524
+ }
525
+ function stringField(record, key) {
526
+ const value = record[key];
527
+ return typeof value === "string" && value !== "" ? value : undefined;
528
+ }
529
+ function booleanField(record, key) {
530
+ const value = record[key];
531
+ return typeof value === "boolean" ? value : undefined;
532
+ }
533
+ function stringArray(value) {
534
+ return Array.isArray(value)
535
+ ? value.filter((item) => typeof item === "string")
536
+ : [];
537
+ }
18
538
  function addVersionDiagnostic(version, rawVersion, diagnostics) {
19
539
  if (version === 2) {
20
540
  return;
@@ -71,6 +71,7 @@ export interface FoundryObjectType {
71
71
  readonly displayMetadata?: FoundryDisplayMetadata;
72
72
  readonly id?: string;
73
73
  readonly interfaces?: readonly string[];
74
+ readonly interfaceImplementations?: readonly FoundryObjectInterfaceImplementation[];
74
75
  readonly primaryKeys?: readonly string[];
75
76
  readonly properties?: readonly FoundryProperty[];
76
77
  readonly rid?: string;
@@ -79,6 +80,14 @@ export interface FoundryObjectType {
79
80
  readonly typeGroups?: readonly string[];
80
81
  readonly [key: string]: unknown;
81
82
  }
83
+ export interface FoundryObjectInterfaceImplementation {
84
+ readonly interfaceApiName: string;
85
+ readonly propertyMappings: readonly FoundryObjectInterfacePropertyMapping[];
86
+ }
87
+ export interface FoundryObjectInterfacePropertyMapping {
88
+ readonly interfacePropertyApiName: string;
89
+ readonly objectPropertyApiName: string;
90
+ }
82
91
  export interface FoundryLinkMetadata {
83
92
  readonly apiName?: string;
84
93
  readonly displayMetadata?: FoundryDisplayMetadata;
@@ -121,17 +130,25 @@ export interface FoundryRelation {
121
130
  export interface FoundryActionParameter {
122
131
  readonly displayMetadata?: FoundryDisplayMetadata;
123
132
  readonly id?: string;
133
+ readonly required?: boolean;
124
134
  readonly type?: {
125
135
  readonly type?: string;
126
136
  readonly [key: string]: unknown;
127
137
  };
138
+ readonly validation?: unknown;
139
+ }
140
+ export interface FoundryActionRule {
141
+ readonly [key: string]: unknown;
142
+ readonly type?: string;
143
+ }
144
+ export interface FoundryActionOperation {
145
+ readonly objectTypeApiName?: string;
146
+ readonly type?: string;
128
147
  }
129
148
  export interface FoundryActionType {
130
149
  readonly actionTypeLogic?: {
131
150
  readonly logic?: {
132
- readonly rules?: readonly {
133
- readonly type?: string;
134
- }[];
151
+ readonly rules?: readonly FoundryActionRule[];
135
152
  };
136
153
  };
137
154
  readonly metadata?: {
@@ -144,19 +161,31 @@ export interface FoundryActionType {
144
161
  readonly rid?: string;
145
162
  readonly status?: FoundryStatus;
146
163
  };
164
+ readonly operations?: readonly FoundryActionOperation[];
147
165
  }
148
166
  export interface FoundryInterfaceProperty {
167
+ readonly apiName?: string;
149
168
  readonly displayName?: string;
150
169
  readonly isSharedProperty?: boolean;
151
170
  readonly required?: boolean;
152
171
  readonly sharedPropertyRid?: string;
153
172
  readonly type?: FoundryBaseType;
154
173
  }
174
+ export interface FoundryInterfaceLink {
175
+ readonly apiName?: string;
176
+ readonly cardinality?: string;
177
+ readonly description?: string;
178
+ readonly displayName?: string;
179
+ readonly linkedEntityApiName?: string;
180
+ readonly linkedEntityType?: string;
181
+ readonly required?: boolean;
182
+ readonly rid?: string;
183
+ }
155
184
  export interface FoundryInterface {
156
185
  readonly apiName?: string;
157
186
  readonly displayMetadata?: FoundryDisplayMetadata;
158
187
  readonly extendsInterfaces?: readonly string[];
159
- readonly links?: readonly unknown[];
188
+ readonly links?: readonly FoundryInterfaceLink[];
160
189
  readonly properties?: readonly FoundryInterfaceProperty[];
161
190
  readonly rid?: string;
162
191
  readonly searchable?: boolean;
@@ -202,6 +231,8 @@ export interface NormalizedObject {
202
231
  readonly apiName: NamePair;
203
232
  readonly description?: string;
204
233
  readonly displayName: string;
234
+ readonly id?: string;
235
+ readonly interfaceImplementations: readonly NormalizedObjectInterfaceImplementation[];
205
236
  readonly pluralDisplayName: string;
206
237
  readonly primaryKeyPropertyApiName: string;
207
238
  readonly properties: readonly NormalizedProperty[];
@@ -211,6 +242,15 @@ export interface NormalizedObject {
211
242
  readonly titlePropertyApiName: string;
212
243
  readonly variableName: string;
213
244
  }
245
+ export interface NormalizedObjectInterfaceImplementation {
246
+ readonly interfaceApiName: NamePair;
247
+ readonly interfaceVariableName: string;
248
+ readonly propertyMappings: readonly NormalizedObjectInterfacePropertyMapping[];
249
+ }
250
+ export interface NormalizedObjectInterfacePropertyMapping {
251
+ readonly interfacePropertyApiName: string;
252
+ readonly objectPropertyApiName: string;
253
+ }
214
254
  export interface NormalizedSharedProperty {
215
255
  readonly apiName: NamePair;
216
256
  readonly array: boolean;
@@ -230,11 +270,34 @@ export interface NormalizedInterface {
230
270
  readonly apiName: NamePair;
231
271
  readonly description?: string;
232
272
  readonly displayName: string;
273
+ readonly extendsInterfaces: readonly NormalizedInterfaceReference[];
274
+ readonly links: readonly NormalizedInterfaceLink[];
275
+ readonly properties: readonly NormalizedInterfaceProperty[];
233
276
  readonly rid?: string;
234
277
  readonly searchable: boolean;
235
278
  readonly status?: string;
236
279
  readonly variableName: string;
237
280
  }
281
+ export interface NormalizedInterfaceReference {
282
+ readonly apiName: NamePair;
283
+ readonly variableName: string;
284
+ }
285
+ export interface NormalizedInterfaceProperty {
286
+ readonly apiName: NamePair;
287
+ readonly displayName: string;
288
+ readonly required: boolean;
289
+ readonly sharedPropertyVariableName?: string;
290
+ readonly type?: unknown;
291
+ }
292
+ export interface NormalizedInterfaceLink {
293
+ readonly apiName: NamePair;
294
+ readonly cardinality: "MANY" | "SINGLE";
295
+ readonly description?: string;
296
+ readonly displayName: string;
297
+ readonly required?: boolean;
298
+ readonly targetApiName: NamePair;
299
+ readonly targetVariableName: string;
300
+ }
238
301
  export interface NormalizedRelation {
239
302
  readonly apiName: NamePair;
240
303
  readonly definition: unknown;
@@ -246,9 +309,19 @@ export interface NormalizedRelation {
246
309
  export interface NormalizedAction {
247
310
  readonly apiName: NamePair;
248
311
  readonly displayName: string;
249
- readonly parameterCount: number;
312
+ readonly parameters: readonly NormalizedActionParameter[];
250
313
  readonly ruleTypes: readonly string[];
314
+ readonly rules: readonly unknown[];
251
315
  readonly status?: string;
316
+ readonly variableName: string;
317
+ }
318
+ export interface NormalizedActionParameter {
319
+ readonly description?: string;
320
+ readonly displayName: string;
321
+ readonly id: NamePair;
322
+ readonly required: boolean;
323
+ readonly type: unknown;
324
+ readonly validationAllowedValues: unknown;
252
325
  }
253
326
  export interface NormalizedTypeGroup {
254
327
  readonly displayName: string;