@n8n/workflow-sdk 0.35.3 → 0.36.1
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/dist/build.tsbuildinfo +1 -1
- package/dist/generate-types/generate-types.d.ts +4 -2
- package/dist/generate-types/generate-types.js +175 -111
- package/dist/generate-types/generate-types.js.map +1 -1
- package/dist/generate-types/generate-zod-schemas.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +4 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/required-subnode-connections.d.ts +36 -0
- package/dist/validation/required-subnode-connections.js +131 -0
- package/dist/validation/required-subnode-connections.js.map +1 -0
- package/dist/validation.d.ts +1 -1
- package/dist/validation.js +3 -1
- package/dist/validation.js.map +1 -1
- package/dist/workflow-builder/group-layout-utils.d.ts +32 -0
- package/dist/workflow-builder/group-layout-utils.js +211 -0
- package/dist/workflow-builder/group-layout-utils.js.map +1 -0
- package/dist/workflow-builder/layout-utils.d.ts +1 -1
- package/dist/workflow-builder/layout-utils.js +212 -203
- package/dist/workflow-builder/layout-utils.js.map +1 -1
- package/dist/workflow-builder/node-builders/node-builder.d.ts +1 -1
- package/dist/workflow-builder/node-builders/node-builder.js +12 -1
- package/dist/workflow-builder/node-builders/node-builder.js.map +1 -1
- package/dist/workflow-builder/subnode-utils.js.map +1 -1
- package/dist/workflow-builder.js +15 -3
- package/dist/workflow-builder.js.map +1 -1
- package/package.json +12 -9
|
@@ -149,10 +149,12 @@ export declare function tryMergeUxForkVariants(a: NodeProperty['displayOptions']
|
|
|
149
149
|
export declare function mapPropertyType(prop: NodeProperty, discriminatorContext?: DiscriminatorCombination): string;
|
|
150
150
|
export declare function extractDiscriminatorCombinations(node: NodeTypeDescription): DiscriminatorCombination[];
|
|
151
151
|
export declare function getPropertiesForCombination(node: NodeTypeDescription, combination: DiscriminatorCombination): NodeProperty[];
|
|
152
|
-
export declare function propertyAppliesToVersion(prop: NodeProperty, version: number): boolean;
|
|
152
|
+
export declare function propertyAppliesToVersion(prop: Pick<NodeProperty, 'displayOptions'>, version: number): boolean;
|
|
153
153
|
export declare function filterPropertiesForVersion(properties: NodeProperty[], version: number): NodeProperty[];
|
|
154
154
|
export declare function generateDiscriminatedUnion(node: NodeTypeDescription): string;
|
|
155
|
-
export declare function generatePropertyJSDoc(prop: NodeProperty, discriminatorContext?: DiscriminatorCombination
|
|
155
|
+
export declare function generatePropertyJSDoc(prop: NodeProperty, discriminatorContext?: DiscriminatorCombination, options?: {
|
|
156
|
+
conditionallyRequired?: boolean;
|
|
157
|
+
}): string;
|
|
156
158
|
export declare function generateNodeJSDoc(node: NodeTypeDescription): string;
|
|
157
159
|
export declare function generatePropertyLine(prop: NodeProperty, optional: boolean, discriminatorContext?: DiscriminatorCombination): string;
|
|
158
160
|
export declare function groupVersionsByProperties(nodes: NodeTypeDescription[]): VersionGroup[];
|
|
@@ -256,6 +256,9 @@ const AI_TYPE_TO_SUBNODE_FIELD = {
|
|
|
256
256
|
canBeMultiple: false,
|
|
257
257
|
},
|
|
258
258
|
};
|
|
259
|
+
function isNodeProperty(option) {
|
|
260
|
+
return typeof option.type === 'string' && typeof option.displayName === 'string';
|
|
261
|
+
}
|
|
259
262
|
function variationApplies(variation, combo) {
|
|
260
263
|
const opts = variation.displayOptions;
|
|
261
264
|
if (!combo)
|
|
@@ -814,7 +817,7 @@ function quotePropertyName(name) {
|
|
|
814
817
|
}
|
|
815
818
|
return name;
|
|
816
819
|
}
|
|
817
|
-
function generateNestedPropertyJSDoc(prop, indent, discriminatorContext) {
|
|
820
|
+
function generateNestedPropertyJSDoc(prop, indent, discriminatorContext, displayOptionsVariants) {
|
|
818
821
|
const lines = [];
|
|
819
822
|
const description = prop.description ?? prop.displayName;
|
|
820
823
|
if (description) {
|
|
@@ -848,45 +851,9 @@ function generateNestedPropertyJSDoc(prop, indent, discriminatorContext) {
|
|
|
848
851
|
if (typeof prop.typeOptions?.loadOptionsMethod === 'string') {
|
|
849
852
|
lines.push(`${indent} * @loadOptionsMethod ${prop.typeOptions.loadOptionsMethod}`);
|
|
850
853
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
if (key === '@version')
|
|
855
|
-
return false;
|
|
856
|
-
const normalizedKey = key.startsWith('/') ? key.slice(1) : key;
|
|
857
|
-
if (discriminatorContext?.[normalizedKey] !== undefined) {
|
|
858
|
-
const showValues = values;
|
|
859
|
-
if (showValues.includes(discriminatorContext[normalizedKey]))
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
return true;
|
|
863
|
-
});
|
|
864
|
-
if (filteredShow.length > 0) {
|
|
865
|
-
const showConditions = filteredShow
|
|
866
|
-
.map(([key, values]) => `${key}: [${values.map((v) => JSON.stringify(v)).join(', ')}]`)
|
|
867
|
-
.join(', ');
|
|
868
|
-
lines.push(`${indent} * @displayOptions.show { ${showConditions} }`);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
if (prop.displayOptions.hide && Object.keys(prop.displayOptions.hide).length > 0) {
|
|
872
|
-
const filteredHide = Object.entries(prop.displayOptions.hide).filter(([key, values]) => {
|
|
873
|
-
if (key === '@version')
|
|
874
|
-
return false;
|
|
875
|
-
const normalizedKey = key.startsWith('/') ? key.slice(1) : key;
|
|
876
|
-
if (discriminatorContext?.[normalizedKey] !== undefined) {
|
|
877
|
-
const hideValues = values;
|
|
878
|
-
if (hideValues.includes(discriminatorContext[normalizedKey]))
|
|
879
|
-
return false;
|
|
880
|
-
}
|
|
881
|
-
return true;
|
|
882
|
-
});
|
|
883
|
-
if (filteredHide.length > 0) {
|
|
884
|
-
const hideConditions = filteredHide
|
|
885
|
-
.map(([key, values]) => `${key}: [${values.map((v) => JSON.stringify(v)).join(', ')}]`)
|
|
886
|
-
.join(', ');
|
|
887
|
-
lines.push(`${indent} * @displayOptions.hide { ${hideConditions} }`);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
854
|
+
const variants = displayOptionsVariants ?? [prop.displayOptions];
|
|
855
|
+
for (const displayOptions of mergeDisplayOptionsVariants(variants, discriminatorContext)) {
|
|
856
|
+
lines.push(...formatDisplayOptionsJSDocLines(displayOptions, indent, discriminatorContext));
|
|
890
857
|
}
|
|
891
858
|
if (prop.default !== undefined && prop.default !== null && prop.default !== '') {
|
|
892
859
|
let defaultStr;
|
|
@@ -903,6 +870,136 @@ function generateNestedPropertyJSDoc(prop, indent, discriminatorContext) {
|
|
|
903
870
|
lines.push(`${indent} */`);
|
|
904
871
|
return lines.join('\n');
|
|
905
872
|
}
|
|
873
|
+
function getResidualDisplayOptions(displayOptions, discriminatorContext) {
|
|
874
|
+
const residual = {};
|
|
875
|
+
if (!displayOptions)
|
|
876
|
+
return residual;
|
|
877
|
+
const keep = ([key]) => {
|
|
878
|
+
if (key === '@version')
|
|
879
|
+
return false;
|
|
880
|
+
const normalizedKey = key.startsWith('/') ? key.slice(1) : key;
|
|
881
|
+
return discriminatorContext?.[normalizedKey] === undefined;
|
|
882
|
+
};
|
|
883
|
+
const show = Object.entries(displayOptions.show ?? {}).filter(keep);
|
|
884
|
+
if (show.length > 0)
|
|
885
|
+
residual.show = Object.fromEntries(show);
|
|
886
|
+
const hide = Object.entries(displayOptions.hide ?? {}).filter(keep);
|
|
887
|
+
if (hide.length > 0)
|
|
888
|
+
residual.hide = Object.fromEntries(hide);
|
|
889
|
+
return residual;
|
|
890
|
+
}
|
|
891
|
+
function hasResidualDisplayOptions(displayOptions, discriminatorContext) {
|
|
892
|
+
const residual = getResidualDisplayOptions(displayOptions, discriminatorContext);
|
|
893
|
+
return residual.show !== undefined || residual.hide !== undefined;
|
|
894
|
+
}
|
|
895
|
+
function formatDisplayOptionsJSDocLines(displayOptions, indent, discriminatorContext) {
|
|
896
|
+
const residual = getResidualDisplayOptions(displayOptions, discriminatorContext);
|
|
897
|
+
const format = (conditions) => Object.entries(conditions)
|
|
898
|
+
.map(([key, values]) => `${key}: [${values.map((v) => JSON.stringify(v)).join(', ')}]`)
|
|
899
|
+
.join(', ');
|
|
900
|
+
const lines = [];
|
|
901
|
+
if (residual.show)
|
|
902
|
+
lines.push(`${indent} * @displayOptions.show { ${format(residual.show)} }`);
|
|
903
|
+
if (residual.hide)
|
|
904
|
+
lines.push(`${indent} * @displayOptions.hide { ${format(residual.hide)} }`);
|
|
905
|
+
return lines;
|
|
906
|
+
}
|
|
907
|
+
function mergeDisplayOptionsVariants(variants, discriminatorContext) {
|
|
908
|
+
const residuals = new Map();
|
|
909
|
+
for (const variant of variants) {
|
|
910
|
+
const residual = getResidualDisplayOptions(variant, discriminatorContext);
|
|
911
|
+
if (residual.show === undefined && residual.hide === undefined)
|
|
912
|
+
return [];
|
|
913
|
+
residuals.set(JSON.stringify(residual), residual);
|
|
914
|
+
}
|
|
915
|
+
const merged = [];
|
|
916
|
+
for (const residual of residuals.values()) {
|
|
917
|
+
const last = merged[merged.length - 1];
|
|
918
|
+
const combined = last
|
|
919
|
+
? (tryMergeUxForkVariants(last, residual) ?? tryMergeShowValueVariants(last, residual))
|
|
920
|
+
: null;
|
|
921
|
+
if (combined) {
|
|
922
|
+
merged[merged.length - 1] = combined;
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
merged.push(residual);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return merged;
|
|
929
|
+
}
|
|
930
|
+
function tryMergeShowValueVariants(a, b) {
|
|
931
|
+
if (a.hide !== undefined || b.hide !== undefined)
|
|
932
|
+
return null;
|
|
933
|
+
if (a.show === undefined || b.show === undefined)
|
|
934
|
+
return null;
|
|
935
|
+
const aShow = a.show;
|
|
936
|
+
const bShow = b.show;
|
|
937
|
+
const keys = Object.keys(aShow);
|
|
938
|
+
if (keys.length !== Object.keys(bShow).length || keys.some((key) => !(key in bShow))) {
|
|
939
|
+
return null;
|
|
940
|
+
}
|
|
941
|
+
const differing = keys.filter((key) => JSON.stringify(aShow[key]) !== JSON.stringify(bShow[key]));
|
|
942
|
+
if (differing.length !== 1)
|
|
943
|
+
return null;
|
|
944
|
+
const [key] = differing;
|
|
945
|
+
const seen = new Set(aShow[key].map((value) => JSON.stringify(value)));
|
|
946
|
+
const values = [...aShow[key], ...bShow[key].filter((v) => !seen.has(JSON.stringify(v)))];
|
|
947
|
+
return { show: { ...aShow, [key]: values } };
|
|
948
|
+
}
|
|
949
|
+
function appliesToCombination(displayOptions, combination) {
|
|
950
|
+
if (!displayOptions || !combination)
|
|
951
|
+
return true;
|
|
952
|
+
const valueFor = (key) => combination[key.startsWith('/') ? key.slice(1) : key];
|
|
953
|
+
for (const [key, conditions] of Object.entries(displayOptions.show ?? {})) {
|
|
954
|
+
const value = valueFor(key);
|
|
955
|
+
if (value !== undefined && !(0, display_options_1.checkConditions)(conditions, [value]))
|
|
956
|
+
return false;
|
|
957
|
+
}
|
|
958
|
+
for (const [key, conditions] of Object.entries(displayOptions.hide ?? {})) {
|
|
959
|
+
const value = valueFor(key);
|
|
960
|
+
if (value !== undefined && (0, display_options_1.checkConditions)(conditions, [value]))
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
963
|
+
return true;
|
|
964
|
+
}
|
|
965
|
+
function emitNestedPropertyLines(properties, indent, discriminatorContext) {
|
|
966
|
+
const variantsByName = new Map();
|
|
967
|
+
for (const prop of properties) {
|
|
968
|
+
if (DISPLAY_ONLY_PROPERTY_TYPES.has(prop.type))
|
|
969
|
+
continue;
|
|
970
|
+
if (!appliesToCombination(prop.displayOptions, discriminatorContext))
|
|
971
|
+
continue;
|
|
972
|
+
const type = mapNestedPropertyType(prop, discriminatorContext);
|
|
973
|
+
if (!type)
|
|
974
|
+
continue;
|
|
975
|
+
const variants = variantsByName.get(prop.name) ?? [];
|
|
976
|
+
variants.push({ prop, type });
|
|
977
|
+
variantsByName.set(prop.name, variants);
|
|
978
|
+
}
|
|
979
|
+
const lines = [];
|
|
980
|
+
for (const [name, variants] of variantsByName) {
|
|
981
|
+
const quotedName = quotePropertyName(name);
|
|
982
|
+
const variantsByType = new Map();
|
|
983
|
+
for (const { prop, type } of variants) {
|
|
984
|
+
const props = variantsByType.get(type) ?? [];
|
|
985
|
+
props.push(prop);
|
|
986
|
+
variantsByType.set(type, props);
|
|
987
|
+
}
|
|
988
|
+
if (variantsByType.size === 1) {
|
|
989
|
+
const [type, props] = Array.from(variantsByType.entries())[0];
|
|
990
|
+
const jsDoc = generateNestedPropertyJSDoc(props[0], indent, discriminatorContext, props.map((p) => p.displayOptions));
|
|
991
|
+
lines.push(`${jsDoc}\n${indent}${quotedName}?: ${type}`);
|
|
992
|
+
continue;
|
|
993
|
+
}
|
|
994
|
+
const memberIndent = indent + INDENT;
|
|
995
|
+
const members = Array.from(variantsByType.entries()).map(([type, props]) => {
|
|
996
|
+
const jsDoc = generateNestedPropertyJSDoc(props[0], memberIndent, discriminatorContext, props.map((p) => p.displayOptions));
|
|
997
|
+
return `${jsDoc}\n${memberIndent}| ${type}`;
|
|
998
|
+
});
|
|
999
|
+
lines.push(`${indent}${quotedName}?:\n${members.join('\n')}`);
|
|
1000
|
+
}
|
|
1001
|
+
return lines;
|
|
1002
|
+
}
|
|
906
1003
|
function generateFixedCollectionType(prop, discriminatorContext) {
|
|
907
1004
|
if (!prop.options || prop.options.length === 0) {
|
|
908
1005
|
return 'Record<string, unknown>';
|
|
@@ -914,18 +1011,7 @@ function generateFixedCollectionType(prop, discriminatorContext) {
|
|
|
914
1011
|
continue;
|
|
915
1012
|
}
|
|
916
1013
|
const groupName = quotePropertyName(group.name);
|
|
917
|
-
const nestedProps =
|
|
918
|
-
for (const nestedProp of group.values) {
|
|
919
|
-
if (DISPLAY_ONLY_PROPERTY_TYPES.has(nestedProp.type)) {
|
|
920
|
-
continue;
|
|
921
|
-
}
|
|
922
|
-
const nestedType = mapNestedPropertyType(nestedProp, discriminatorContext);
|
|
923
|
-
if (nestedType) {
|
|
924
|
-
const quotedName = quotePropertyName(nestedProp.name);
|
|
925
|
-
const jsDoc = generateNestedPropertyJSDoc(nestedProp, INDENT.repeat(3), discriminatorContext);
|
|
926
|
-
nestedProps.push(`${jsDoc}\n${INDENT.repeat(3)}${quotedName}?: ${nestedType}`);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
1014
|
+
const nestedProps = emitNestedPropertyLines(group.values, INDENT.repeat(3), discriminatorContext);
|
|
929
1015
|
if (nestedProps.length > 0) {
|
|
930
1016
|
const innerType = `{\n${nestedProps.join(';\n')};\n${INDENT.repeat(2)}}`;
|
|
931
1017
|
const minRequired = prop.typeOptions?.minRequiredFields;
|
|
@@ -1139,22 +1225,10 @@ function generateCollectionType(prop, discriminatorContext) {
|
|
|
1139
1225
|
if (!prop.options || prop.options.length === 0) {
|
|
1140
1226
|
return 'Record<string, unknown>';
|
|
1141
1227
|
}
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
}
|
|
1147
|
-
const nestedType = nestedProp.type;
|
|
1148
|
-
if (DISPLAY_ONLY_PROPERTY_TYPES.has(nestedType)) {
|
|
1149
|
-
continue;
|
|
1150
|
-
}
|
|
1151
|
-
const propType = mapNestedPropertyType(nestedProp, discriminatorContext);
|
|
1152
|
-
if (propType) {
|
|
1153
|
-
const quotedName = quotePropertyName(nestedProp.name);
|
|
1154
|
-
const jsDoc = generateNestedPropertyJSDoc(nestedProp, INDENT.repeat(2), discriminatorContext);
|
|
1155
|
-
nestedProps.push(`${jsDoc}\n${INDENT.repeat(2)}${quotedName}?: ${propType}`);
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1228
|
+
const nestedProperties = prop.options
|
|
1229
|
+
.filter((option) => option.values === undefined)
|
|
1230
|
+
.filter(isNodeProperty);
|
|
1231
|
+
const nestedProps = emitNestedPropertyLines(nestedProperties, INDENT.repeat(2), discriminatorContext);
|
|
1158
1232
|
if (nestedProps.length === 0) {
|
|
1159
1233
|
return 'Record<string, unknown>';
|
|
1160
1234
|
}
|
|
@@ -1413,8 +1487,33 @@ function propertyAppliesToVersion(prop, version) {
|
|
|
1413
1487
|
}
|
|
1414
1488
|
return true;
|
|
1415
1489
|
}
|
|
1490
|
+
function filterNestedOptionsForVersion(prop, version) {
|
|
1491
|
+
if (!prop.options)
|
|
1492
|
+
return prop;
|
|
1493
|
+
let changed = false;
|
|
1494
|
+
const options = [];
|
|
1495
|
+
for (const option of prop.options) {
|
|
1496
|
+
if (!propertyAppliesToVersion(option, version)) {
|
|
1497
|
+
changed = true;
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
let next = filterNestedOptionsForVersion(option, version);
|
|
1501
|
+
if (next.values) {
|
|
1502
|
+
const values = filterPropertiesForVersion(next.values, version);
|
|
1503
|
+
if (values.length !== next.values.length || values.some((v, i) => v !== next.values?.[i])) {
|
|
1504
|
+
next = { ...next, values };
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
if (next !== option)
|
|
1508
|
+
changed = true;
|
|
1509
|
+
options.push(next);
|
|
1510
|
+
}
|
|
1511
|
+
return changed ? { ...prop, options } : prop;
|
|
1512
|
+
}
|
|
1416
1513
|
function filterPropertiesForVersion(properties, version) {
|
|
1417
|
-
return properties
|
|
1514
|
+
return properties
|
|
1515
|
+
.filter((prop) => propertyAppliesToVersion(prop, version))
|
|
1516
|
+
.map((prop) => filterNestedOptionsForVersion(prop, version));
|
|
1418
1517
|
}
|
|
1419
1518
|
function generateDiscriminatedUnion(node) {
|
|
1420
1519
|
const combinations = extractDiscriminatorCombinations(node);
|
|
@@ -1477,7 +1576,7 @@ function generateDiscriminatedUnion(node) {
|
|
|
1477
1576
|
}
|
|
1478
1577
|
return lines.join('\n');
|
|
1479
1578
|
}
|
|
1480
|
-
function generatePropertyJSDoc(prop, discriminatorContext) {
|
|
1579
|
+
function generatePropertyJSDoc(prop, discriminatorContext, options) {
|
|
1481
1580
|
const lines = ['/**'];
|
|
1482
1581
|
const description = prop.description ?? prop.displayName;
|
|
1483
1582
|
const safeDescription = description
|
|
@@ -1506,45 +1605,9 @@ function generatePropertyJSDoc(prop, discriminatorContext) {
|
|
|
1506
1605
|
if (typeof prop.typeOptions?.loadOptionsMethod === 'string') {
|
|
1507
1606
|
lines.push(` * @loadOptionsMethod ${prop.typeOptions.loadOptionsMethod}`);
|
|
1508
1607
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
if (key === '@version')
|
|
1513
|
-
return false;
|
|
1514
|
-
const normalizedKey = key.startsWith('/') ? key.slice(1) : key;
|
|
1515
|
-
if (discriminatorContext?.[normalizedKey] !== undefined) {
|
|
1516
|
-
const showValues = values;
|
|
1517
|
-
if (showValues.includes(discriminatorContext[normalizedKey]))
|
|
1518
|
-
return false;
|
|
1519
|
-
}
|
|
1520
|
-
return true;
|
|
1521
|
-
});
|
|
1522
|
-
if (filteredShow.length > 0) {
|
|
1523
|
-
const showConditions = filteredShow
|
|
1524
|
-
.map(([key, values]) => `${key}: [${values.map((v) => JSON.stringify(v)).join(', ')}]`)
|
|
1525
|
-
.join(', ');
|
|
1526
|
-
lines.push(` * @displayOptions.show { ${showConditions} }`);
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
if (prop.displayOptions.hide && Object.keys(prop.displayOptions.hide).length > 0) {
|
|
1530
|
-
const filteredHide = Object.entries(prop.displayOptions.hide).filter(([key, values]) => {
|
|
1531
|
-
if (key === '@version')
|
|
1532
|
-
return false;
|
|
1533
|
-
const normalizedKey = key.startsWith('/') ? key.slice(1) : key;
|
|
1534
|
-
if (discriminatorContext?.[normalizedKey] !== undefined) {
|
|
1535
|
-
const hideValues = values;
|
|
1536
|
-
if (hideValues.includes(discriminatorContext[normalizedKey]))
|
|
1537
|
-
return false;
|
|
1538
|
-
}
|
|
1539
|
-
return true;
|
|
1540
|
-
});
|
|
1541
|
-
if (filteredHide.length > 0) {
|
|
1542
|
-
const hideConditions = filteredHide
|
|
1543
|
-
.map(([key, values]) => `${key}: [${values.map((v) => JSON.stringify(v)).join(', ')}]`)
|
|
1544
|
-
.join(', ');
|
|
1545
|
-
lines.push(` * @displayOptions.hide { ${hideConditions} }`);
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1608
|
+
lines.push(...formatDisplayOptionsJSDocLines(prop.displayOptions, '', discriminatorContext));
|
|
1609
|
+
if (options?.conditionallyRequired) {
|
|
1610
|
+
lines.push(' * @required when the displayOptions conditions above match');
|
|
1548
1611
|
}
|
|
1549
1612
|
if (prop.default !== undefined && prop.default !== null && prop.default !== '') {
|
|
1550
1613
|
let defaultStr;
|
|
@@ -1598,18 +1661,19 @@ function generatePropertyLine(prop, optional, discriminatorContext) {
|
|
|
1598
1661
|
return '';
|
|
1599
1662
|
}
|
|
1600
1663
|
const lines = [];
|
|
1664
|
+
const conditionallyRequired = !optional && hasResidualDisplayOptions(prop.displayOptions, discriminatorContext);
|
|
1601
1665
|
const hasDisplayOptions = prop.displayOptions &&
|
|
1602
1666
|
((prop.displayOptions.show && Object.keys(prop.displayOptions.show).length > 0) ||
|
|
1603
1667
|
(prop.displayOptions.hide && Object.keys(prop.displayOptions.hide).length > 0));
|
|
1604
1668
|
if (prop.description || hasDisplayOptions || prop.hint || prop.builderHint) {
|
|
1605
|
-
lines.push(generatePropertyJSDoc(prop, discriminatorContext));
|
|
1669
|
+
lines.push(generatePropertyJSDoc(prop, discriminatorContext, { conditionallyRequired }));
|
|
1606
1670
|
}
|
|
1607
1671
|
let propName = prop.name;
|
|
1608
1672
|
const needsQuoting = RESERVED_WORDS.has(propName) || !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(propName);
|
|
1609
1673
|
if (needsQuoting) {
|
|
1610
1674
|
propName = `'${propName.replace(/'/g, "\\'")}'`;
|
|
1611
1675
|
}
|
|
1612
|
-
const optionalMarker = optional ? '?' : '';
|
|
1676
|
+
const optionalMarker = optional || conditionallyRequired ? '?' : '';
|
|
1613
1677
|
lines.push(`${INDENT}${propName}${optionalMarker}: ${tsType};`);
|
|
1614
1678
|
return lines.join(`\n${INDENT}`);
|
|
1615
1679
|
}
|