@servicenow/sdk-build-plugins 4.6.0 → 4.6.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.
Files changed (45) hide show
  1. package/dist/acl-plugin.js +3 -1
  2. package/dist/acl-plugin.js.map +1 -1
  3. package/dist/atf/test-plugin.js +6 -8
  4. package/dist/atf/test-plugin.js.map +1 -1
  5. package/dist/basic-syntax-plugin.js +10 -3
  6. package/dist/basic-syntax-plugin.js.map +1 -1
  7. package/dist/column-plugin.js +96 -42
  8. package/dist/column-plugin.js.map +1 -1
  9. package/dist/now-config-plugin.js +1 -0
  10. package/dist/now-config-plugin.js.map +1 -1
  11. package/dist/record-plugin.js +3 -2
  12. package/dist/record-plugin.js.map +1 -1
  13. package/dist/script-include-plugin.js +4 -0
  14. package/dist/script-include-plugin.js.map +1 -1
  15. package/dist/service-catalog/catalog-clientscript-plugin.js +2 -2
  16. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -1
  17. package/dist/service-catalog/catalog-ui-policy-plugin.js +2 -2
  18. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -1
  19. package/dist/service-catalog/service-catalog-base.d.ts +2 -2
  20. package/dist/service-catalog/service-catalog-base.js +2 -2
  21. package/dist/service-catalog/service-catalog-base.js.map +1 -1
  22. package/dist/service-catalog/utils.js +1 -1
  23. package/dist/service-catalog/utils.js.map +1 -1
  24. package/dist/table-plugin.js +201 -55
  25. package/dist/table-plugin.js.map +1 -1
  26. package/dist/ui-policy-plugin.js +28 -96
  27. package/dist/ui-policy-plugin.js.map +1 -1
  28. package/dist/utils.d.ts +5 -1
  29. package/dist/utils.js +41 -0
  30. package/dist/utils.js.map +1 -1
  31. package/package.json +4 -4
  32. package/src/acl-plugin.ts +3 -1
  33. package/src/atf/test-plugin.ts +6 -9
  34. package/src/basic-syntax-plugin.ts +11 -3
  35. package/src/column-plugin.ts +134 -67
  36. package/src/now-config-plugin.ts +1 -0
  37. package/src/record-plugin.ts +11 -3
  38. package/src/script-include-plugin.ts +8 -0
  39. package/src/service-catalog/catalog-clientscript-plugin.ts +2 -2
  40. package/src/service-catalog/catalog-ui-policy-plugin.ts +2 -2
  41. package/src/service-catalog/service-catalog-base.ts +2 -2
  42. package/src/service-catalog/utils.ts +1 -1
  43. package/src/table-plugin.ts +254 -77
  44. package/src/ui-policy-plugin.ts +32 -128
  45. package/src/utils.ts +52 -0
@@ -59,6 +59,10 @@ const ColumnSchema = zod_1.z
59
59
  '@_use_dynamic_default': BooleanFromString.optional(),
60
60
  '@_reference': zod_1.z.string().optional(),
61
61
  '@_virtual': BooleanFromString.optional(),
62
+ '@_formula': zod_1.z.string().optional(),
63
+ '@_virtual_type': zod_1.z.string().optional(),
64
+ '@_use_reference_qualifier': zod_1.z.string().optional(),
65
+ '@_dynamic_ref_qual': zod_1.z.string().optional(),
62
66
  '@_calculation': zod_1.z.string().optional(),
63
67
  '@_choice_field': zod_1.z.string().optional(),
64
68
  '@_function_definition': zod_1.z.string().optional(),
@@ -188,7 +192,11 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
188
192
  records.push(await factory.createRecord({
189
193
  source: file,
190
194
  table,
191
- properties: filterUndefinedProperties(rec),
195
+ properties: {
196
+ ...filterUndefinedProperties(rec),
197
+ // Decorate generated sys_db_object
198
+ ...(key === 'sysDbObject' || key === 'sysDictionary' ? { _bootstrap: true } : {}),
199
+ },
192
200
  }));
193
201
  }
194
202
  }
@@ -291,25 +299,37 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
291
299
  override.transform(({ $ }) => ({
292
300
  baseTable: $.from('base_table'),
293
301
  default: $.from('default_value_override', 'default_value').map((flag, value) => {
294
- return flag.toBoolean()?.getValue() ? value.ifString()?.getValue() : undefined;
302
+ return flag.ifDefined() && flag.toBoolean()?.getValue()
303
+ ? value.ifString()?.getValue()
304
+ : undefined;
295
305
  }),
296
306
  calculation: $.from('calculation_override', 'calculation').map((flag, value) => {
297
- return flag.toBoolean()?.getValue() ? value.ifString()?.getValue() : undefined;
307
+ return flag.ifDefined() && flag.toBoolean()?.getValue()
308
+ ? value.ifString()?.getValue()
309
+ : undefined;
298
310
  }),
299
311
  referenceQualifier: $.from('reference_qual_override', 'reference_qual').map((flag, value) => {
300
- return flag.toBoolean()?.getValue() ? value.ifString()?.getValue() : undefined;
312
+ return flag.ifDefined() && flag.toBoolean()?.getValue()
313
+ ? value.ifString()?.getValue()
314
+ : undefined;
301
315
  }),
302
316
  readOnlyOption: $.from('read_only_option_override', 'read_only_option').map((flag, value) => {
303
- return flag.toBoolean()?.getValue() ? value.ifString()?.getValue() : undefined;
317
+ return flag.ifDefined() && flag.toBoolean()?.getValue()
318
+ ? value.ifString()?.getValue()
319
+ : undefined;
304
320
  }),
305
321
  dependent: $.from('dependent_override', 'dependent').map((flag, value) => {
306
- return flag.toBoolean()?.getValue() ? value.ifString()?.getValue() : undefined;
322
+ return flag.ifDefined() && flag.toBoolean()?.getValue()
323
+ ? value.ifString()?.getValue()
324
+ : undefined;
307
325
  }),
308
326
  mandatory: $.from('mandatory_override', 'mandatory').map((flag, value) => {
309
- return flag.toBoolean()?.getValue() ? value.toBoolean()?.getValue() : undefined;
327
+ return flag.ifDefined() && flag.toBoolean()?.getValue()
328
+ ? value.toBoolean()?.getValue()
329
+ : undefined;
310
330
  }),
311
331
  attributes: $.from('attributes_override', 'attributes').map((flag, attrs) => {
312
- if (!flag.toBoolean()?.getValue() || !attrs.isString()) {
332
+ if (!flag.ifDefined() || !flag.toBoolean()?.getValue() || !attrs.isString()) {
313
333
  return undefined;
314
334
  }
315
335
  const result = {};
@@ -362,6 +382,38 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
362
382
  const originalSource = record.getOriginalSource();
363
383
  // Avoid replacing call expressions with variable statements
364
384
  const writeAsCallExpression = sdk_build_core_1.ts.Node.isNode(originalSource) && originalSource.isKind(sdk_build_core_1.ts.SyntaxKind.CallExpression);
385
+ const tableName = record.get('name').asString().getValue();
386
+ const isBootstrapDbObject = record.get('_bootstrap').ifBoolean()?.getValue() === true;
387
+ const nonBootstrapColumns = columns.filter((col) => col.get('_bootstrap').ifBoolean()?.getValue() !== true);
388
+ // Write as augmentation if we have sys_db_object from bootstrap and columns from elsewhere
389
+ const isAugmentation = isBootstrapDbObject && nonBootstrapColumns.length > 0;
390
+ if (isAugmentation) {
391
+ const augmentsExpression = new sdk_build_core_1.CallExpressionShape({
392
+ source: record,
393
+ callee: 'Table',
394
+ exportName: tableName,
395
+ args: [
396
+ record.transform(({ $ }) => ({
397
+ augments: $.val(tableName),
398
+ schema: $.val(schema),
399
+ })),
400
+ ],
401
+ });
402
+ return {
403
+ success: true,
404
+ value: writeAsCallExpression
405
+ ? augmentsExpression
406
+ : new sdk_build_core_1.VariableStatementShape({
407
+ source: record,
408
+ isExported: true,
409
+ variableName: new sdk_build_core_1.IdentifierShape({
410
+ source: record,
411
+ name: tableName,
412
+ }),
413
+ initializer: augmentsExpression,
414
+ }),
415
+ };
416
+ }
365
417
  const callExpression = new sdk_build_core_1.CallExpressionShape({
366
418
  source: record,
367
419
  callee: 'Table',
@@ -468,7 +520,7 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
468
520
  }),
469
521
  }));
470
522
  })).def([]),
471
- label: $.map((label) => label.ifString() ??
523
+ label: $.map((label) => label.ifString()?.ifNotEmpty() ??
472
524
  (tableDocumentation.length &&
473
525
  !(0, column_plugin_1.isDefaultDocumentation)('', tableDocumentation, config.defaultLanguage)
474
526
  ? tableDocumentation.map((doc) => doc
@@ -542,11 +594,12 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
542
594
  };
543
595
  },
544
596
  async toFile(record, { descendants, config, transform }) {
545
- if (config.tableOutputFormat !== 'bootstrap' || config.type === 'configuration' || record.isDeleted()) {
546
- // Defer to record plugin
597
+ if (record.isDeleted()) {
547
598
  return { success: false };
548
599
  }
549
- const tableName = record.get('name').asString().getValue();
600
+ const augmentsValue = record.get('augments').ifString()?.getValue();
601
+ const isAugmentation = augmentsValue !== undefined;
602
+ const tableName = augmentsValue ?? record.get('name').asString().getValue();
550
603
  const columns = descendants.query('sys_dictionary');
551
604
  const choices = descendants.query('sys_choice');
552
605
  const indexes = descendants.query('sys_index');
@@ -554,6 +607,42 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
554
607
  const licensing = descendants.query('ua_table_licensing_config');
555
608
  const autoNumber = descendants.query('sys_number');
556
609
  const overrides = descendants.query('sys_dictionary_override');
610
+ const [documentationFiles, licensingFiles, autoNumberFiles, overrideFiles, sysDictionaryFiles, sysDbObjectFiles,] = await Promise.all([
611
+ generateRecordXml(documentation.filter((doc) => !(0, column_plugin_1.isDefaultDocumentation)(doc.get('element')?.toString().getValue(), [doc], config.defaultLanguage)), config, transform),
612
+ generateRecordXml(licensing.filter((l) => !isDefaultLicenseConfig(tableName, l)), config, transform),
613
+ generateRecordXml(autoNumber, config, transform),
614
+ generateRecordXml(overrides, config, transform),
615
+ generateRecordXml(columns, config, transform, ['_bootstrap']),
616
+ isAugmentation
617
+ ? Promise.resolve([])
618
+ : generateRecordXml([record], config, transform, ['augments', '_bootstrap']),
619
+ ]);
620
+ if (config.type === 'configuration') {
621
+ // No bootstrap XML for configuration projects, just write independent record XML
622
+ const choiceSets = descendants.query('sys_choice_set');
623
+ const [choiceSetFiles, indexFiles] = await Promise.all([
624
+ Promise.all(choiceSets.map((cs) => {
625
+ const csChoices = choices.filter((c) => c.get('name').toString().getValue() === cs.get('name').toString().getValue() &&
626
+ c.get('element').toString().getValue() ===
627
+ cs.get('element').toString().getValue());
628
+ return (0, utils_1.generateChoiceSetFile)(cs, csChoices, config, transform);
629
+ })),
630
+ generateRecordXml(indexes, config, transform),
631
+ ]);
632
+ return {
633
+ success: true,
634
+ value: [
635
+ ...sysDictionaryFiles,
636
+ ...choiceSetFiles,
637
+ ...indexFiles,
638
+ ...sysDbObjectFiles,
639
+ ...documentationFiles,
640
+ ...licensingFiles,
641
+ ...autoNumberFiles,
642
+ ...overrideFiles,
643
+ ],
644
+ };
645
+ }
557
646
  let displayColumn;
558
647
  let collectionRecord;
559
648
  const elements = [];
@@ -626,6 +715,23 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
626
715
  ['hint', column.get('hint').ifString()?.getValue()],
627
716
  ['help', column.get('help').ifString()?.getValue()],
628
717
  ['virtual', column.get('virtual').ifBoolean()?.getValue().toString()],
718
+ ['formula', column.get('formula').ifString()?.getValue() || undefined],
719
+ [
720
+ 'virtual_type',
721
+ column.get('virtual_type').ifString()?.getValue() === 'script'
722
+ ? undefined
723
+ : column.get('virtual_type').ifString()?.getValue(),
724
+ ],
725
+ [
726
+ 'use_reference_qualifier',
727
+ column.get('use_reference_qualifier').ifString()?.getValue() === 'simple'
728
+ ? undefined
729
+ : column.get('use_reference_qualifier').ifString()?.getValue(),
730
+ ],
731
+ [
732
+ 'dynamic_ref_qual',
733
+ column.get('dynamic_ref_qual').ifDefined()?.toString().getValue() || undefined,
734
+ ],
629
735
  ['widget', column.get('widget').ifString()?.getValue()],
630
736
  ['reference_qual', column.get('reference_qual').ifString()?.getValue()],
631
737
  ['reference_qual_condition', column.get('reference_qual_condition').ifString()?.getValue()],
@@ -692,10 +798,6 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
692
798
  ...indexElements,
693
799
  ]),
694
800
  ]).end({ prettyPrint: true });
695
- const documentationFiles = await generateRecordXml(documentation.filter((doc) => !(0, column_plugin_1.isDefaultDocumentation)(doc.get('element')?.toString().getValue(), [doc], config.defaultLanguage)), config, transform);
696
- const licensingFiles = await generateRecordXml(licensing.filter((licensing) => !isDefaultLicenseConfig(tableName, licensing)), config, transform);
697
- const autoNumberFiles = await generateRecordXml(autoNumber, config, transform);
698
- const overrideFiles = await generateRecordXml(overrides, config, transform);
699
801
  return {
700
802
  success: true,
701
803
  value: [
@@ -709,6 +811,8 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
709
811
  ...licensingFiles,
710
812
  ...autoNumberFiles,
711
813
  ...overrideFiles,
814
+ ...sysDictionaryFiles,
815
+ ...sysDbObjectFiles,
712
816
  ],
713
817
  };
714
818
  },
@@ -759,20 +863,33 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
759
863
  const table = callExpression.getArgument(0).asObject().withAliasedKeys(tableAliases);
760
864
  (0, utils_1.generateDeprecatedDiagnostics)(table, diagnostics);
761
865
  const relatedRecords = [];
762
- const tableName = table.get('name').asString();
866
+ const augments = table.get('augments').ifString();
867
+ const isAugmentation = augments !== undefined;
868
+ const tableName = isAugmentation ? augments : table.get('name').asString();
763
869
  if (!tableName.getValue().match(tableNameRegex)) {
764
870
  diagnostics.error(table.get('name'), 'Table name must only contain lowercase letters, numbers, and underscores and end with a letter or number');
765
871
  }
766
872
  let ignoreColumnNameCheck = false;
767
873
  const scopeName = config.scope;
768
- const scopeRegex = new RegExp(`^${scopeName}_`);
769
- const globalRegex = /^u_/;
770
- const tableNameMatch = tableName.getValue().match(scopeRegex);
771
- if (!tableNameMatch && !(0, sdk_build_core_1.isSNScope)(scopeName) && scopeName !== 'global') {
874
+ const scopePrefix = scopeName === 'global' ? 'u_' : `${scopeName}_`;
875
+ const prefixRegex = new RegExp(`^${scopePrefix}`);
876
+ const tableNameMatch = tableName.getValue().match(prefixRegex);
877
+ if (isAugmentation) {
878
+ if (tableNameMatch && scopeName !== 'global') {
879
+ const nameNode = tableName.getOriginalNode();
880
+ if (!nameNode?.getParentIfKind(sdk_build_core_1.ts.SyntaxKind.AsExpression)) {
881
+ diagnostics.error(table.get('augments'), `'augments' flag set on in-scope table '${tableName.getValue()}'`);
882
+ }
883
+ else {
884
+ ignoreColumnNameCheck = true;
885
+ }
886
+ }
887
+ }
888
+ else if (!tableNameMatch && !(0, sdk_build_core_1.isSNScope)(scopeName) && scopeName !== 'global') {
772
889
  const nameNode = tableName.getOriginalNode();
773
890
  if (nameNode && !nameNode.getParentIfKind(sdk_build_core_1.ts.SyntaxKind.AsExpression)) {
774
891
  // 'sn' and 'now' scoped apps ignore this validation
775
- diagnostics.error(table.get('name'), `'name' property should start with scope prefix '${scopeName}_'`);
892
+ diagnostics.error(table.get('name'), `'name' property should start with scope prefix '${scopePrefix}'`);
776
893
  }
777
894
  else {
778
895
  ignoreColumnNameCheck = true;
@@ -785,12 +902,11 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
785
902
  if (!exportedByName) {
786
903
  diagnostics.error(callExpression, `Table definition should be exported as a named export with the name '${tableName.getValue()}'`);
787
904
  }
788
- const globalTableNameMatch = tableName.getValue().match(globalRegex);
789
905
  let anyNonPrefixedGlobalColumn = false;
790
- if (scopeName === 'global' && !globalTableNameMatch) {
906
+ if (!isAugmentation && scopeName === 'global' && !tableNameMatch) {
791
907
  const schema = table.get('schema').asObject();
792
908
  for (const [name, _] of schema.entries()) {
793
- if (!name.match(globalRegex)) {
909
+ if (!name.match(prefixRegex)) {
794
910
  anyNonPrefixedGlobalColumn = true;
795
911
  break;
796
912
  }
@@ -799,7 +915,7 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
799
915
  diagnostics.error(table.get('name'), `Global table 'name' property should start with custom prefix 'u_'`);
800
916
  }
801
917
  }
802
- else if (scopeName === 'global') {
918
+ else if (scopeName === 'global' && !isAugmentation) {
803
919
  // Global table starts with custom prefix `u_`, allow any column name prefix
804
920
  ignoreColumnNameCheck = true;
805
921
  }
@@ -880,16 +996,22 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
880
996
  }
881
997
  else {
882
998
  // Handle regular column - create sys_dictionary record
883
- if (!ignoreColumnNameCheck &&
999
+ if (isAugmentation && !tableNameMatch) {
1000
+ if (!(0, sdk_build_core_1.isSNScope)(scopeName) && !name.match(prefixRegex)) {
1001
+ diagnostics.error(column.getOriginalNode().getParentIfKind(sdk_build_core_1.ts.SyntaxKind.PropertyAssignment) ??
1002
+ column, `Column name '${name}' must be prefixed with '${scopePrefix}' when augmenting a table`);
1003
+ }
1004
+ }
1005
+ else if (!ignoreColumnNameCheck &&
884
1006
  !tableNameMatch &&
885
1007
  !(0, sdk_build_core_1.isSNScope)(scopeName) &&
886
1008
  scopeName !== 'global' &&
887
- !name.match(scopeRegex)) {
1009
+ !name.match(prefixRegex)) {
888
1010
  // 'sn' and 'now' scoped apps ignore this validation
889
- diagnostics.error(column.getOriginalNode().getParentIfKind(sdk_build_core_1.ts.SyntaxKind.PropertyAssignment) ?? column, `Column name should be prefixed with scope '${scopeName}_' if table name does not contain prefix`);
1011
+ diagnostics.error(column.getOriginalNode().getParentIfKind(sdk_build_core_1.ts.SyntaxKind.PropertyAssignment) ?? column, `Column name should be prefixed with scope '${scopePrefix}' if table name does not contain prefix`);
890
1012
  }
891
- else if (scopeName === 'global' && !globalTableNameMatch && !name.match(globalRegex)) {
892
- diagnostics.error(column.getOriginalNode().getParentIfKind(sdk_build_core_1.ts.SyntaxKind.PropertyAssignment) ?? column, `Column name should be prefixed with 'u_' custom prefix if table name does not contain this prefix, such as when adding columns to an existing global table`);
1013
+ else if (scopeName === 'global' && !tableNameMatch && !name.match(prefixRegex)) {
1014
+ diagnostics.error(column.getOriginalNode().getParentIfKind(sdk_build_core_1.ts.SyntaxKind.PropertyAssignment) ?? column, `Column name should be prefixed with '${scopePrefix}' custom prefix if table name does not contain this prefix, such as when adding columns to an existing global table`);
893
1015
  }
894
1016
  const display = table.get('display').ifString()?.getValue() === name;
895
1017
  const result = await transform.toRecord((0, column_helper_1.addFieldsToColumn)({ name, table: tableName.getValue(), display }, column.as(sdk_build_core_1.CallExpressionShape)));
@@ -1038,27 +1160,30 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
1038
1160
  relatedRecords.push(sysNumberRecord);
1039
1161
  }
1040
1162
  // sys_dictionary (collection)
1041
- relatedRecords.push(await factory.createRecord({
1042
- source: statement ?? callExpression,
1043
- table: 'sys_dictionary',
1044
- properties: table.transform(({ $ }) => ({
1045
- name: $,
1046
- element: $.val(undefined),
1047
- internal_type: $.def('collection'),
1048
- attributes: $.map((attributes) => {
1049
- if (!attributes.isObject()) {
1050
- return undefined;
1051
- }
1052
- const attributesObj = attributes.asObject().getValue();
1053
- return Object.entries(attributesObj)
1054
- .map(([key, value]) => `${key}=${value}`)
1055
- .join(',');
1056
- }).def(''),
1057
- audit: $.def(false),
1058
- read_only: $.from('readOnly').def(false),
1059
- text_index: $.from('textIndex').def(false),
1060
- })),
1061
- }));
1163
+ if (!isAugmentation) {
1164
+ relatedRecords.push(await factory.createRecord({
1165
+ source: statement ?? callExpression,
1166
+ table: 'sys_dictionary',
1167
+ properties: table.transform(({ $ }) => ({
1168
+ name: $,
1169
+ element: $.val(undefined),
1170
+ internal_type: $.def('collection'),
1171
+ active: $.val(true),
1172
+ attributes: $.map((attributes) => {
1173
+ if (!attributes.isObject()) {
1174
+ return undefined;
1175
+ }
1176
+ const attributesObj = attributes.asObject().getValue();
1177
+ return Object.entries(attributesObj)
1178
+ .map(([key, value]) => `${key}=${value}`)
1179
+ .join(',');
1180
+ }).def(''),
1181
+ audit: $.def(false),
1182
+ read_only: $.from('readOnly').def(false),
1183
+ text_index: $.from('textIndex').def(false),
1184
+ })),
1185
+ }));
1186
+ }
1062
1187
  const hasAction = (actionName, actions) => {
1063
1188
  return actions
1064
1189
  .ifArray()
@@ -1101,8 +1226,10 @@ exports.TablePlugin = sdk_build_core_1.Plugin.create({
1101
1226
  is_extendable: $.from('extensible').toBoolean().def(false),
1102
1227
  label: $.map((label) => (0, column_to_record_1.getLabelForDefaultLanguage)(label, config.defaultLanguage)),
1103
1228
  live_feed_enabled: $.from('liveFeed').toBoolean().def(false),
1104
- name: $,
1229
+ name: $.from('name', 'augments').map((nameVal, augmentsVal) => augmentsVal.ifString() ?? nameVal),
1105
1230
  scriptable_table: $.from('scriptableTable').toBoolean().def(false),
1231
+ // Controls toFile output, not written to record XML
1232
+ augments: $.from('augments'),
1106
1233
  })),
1107
1234
  });
1108
1235
  if (exportedByName) {
@@ -1186,6 +1313,16 @@ function parseTableBootstrapXml(xml) {
1186
1313
  useDynamicDefault: column['@_use_dynamic_default'],
1187
1314
  reference: column['@_reference'],
1188
1315
  isVirtual: column['@_virtual'],
1316
+ formula: column['@_formula'],
1317
+ virtualType: column['@_virtual_type'] === 'script' || column['@_virtual_type'] === 'formula'
1318
+ ? column['@_virtual_type']
1319
+ : undefined,
1320
+ useReferenceQualifier: column['@_use_reference_qualifier'] === 'simple' ||
1321
+ column['@_use_reference_qualifier'] === 'dynamic' ||
1322
+ column['@_use_reference_qualifier'] === 'advanced'
1323
+ ? column['@_use_reference_qualifier']
1324
+ : undefined,
1325
+ dynamicRefQual: column['@_dynamic_ref_qual'],
1189
1326
  calculation: column['@_calculation'],
1190
1327
  choiceField: column['@_choice_field'],
1191
1328
  functionDefinition: column['@_function_definition'],
@@ -1313,6 +1450,10 @@ function tableDefToRecordProperties(tableDef, tableDefaultLanguage = 'en') {
1313
1450
  use_dynamic_default: column.useDynamicDefault,
1314
1451
  reference: column.reference,
1315
1452
  virtual: column.isVirtual,
1453
+ formula: column.formula,
1454
+ virtual_type: column.virtualType,
1455
+ use_reference_qualifier: column.useReferenceQualifier,
1456
+ dynamic_ref_qual: column.dynamicRefQual,
1316
1457
  default: column.defaultValue,
1317
1458
  calculation: column.calculation,
1318
1459
  choice_field: column.choiceField,
@@ -1392,6 +1533,10 @@ function tableDefToRecordProperties(tableDef, tableDefaultLanguage = 'en') {
1392
1533
  use_dynamic_default: undefined,
1393
1534
  reference: undefined,
1394
1535
  virtual: undefined,
1536
+ formula: undefined,
1537
+ virtual_type: undefined,
1538
+ use_reference_qualifier: undefined,
1539
+ dynamic_ref_qual: undefined,
1395
1540
  default: undefined,
1396
1541
  calculation: undefined,
1397
1542
  choice_field: undefined,
@@ -1443,7 +1588,7 @@ function addTableToGlobalGeneratedFile(tableArg, sourceFilePath, compiler) {
1443
1588
  namedImports: [],
1444
1589
  };
1445
1590
  const generatedTableFile = compiler.getGeneratedTableFile();
1446
- const tableName = tableArg.get('name').asString().getValue();
1591
+ const tableName = tableArg.get('augments').ifString()?.getValue() ?? tableArg.get('name').asString().getValue();
1447
1592
  if (!(tableName.trim().length > 0 && tableName.match(tableNameRegex))) {
1448
1593
  return;
1449
1594
  }
@@ -1519,7 +1664,7 @@ function createElement(name, attributes = [], children = []) {
1519
1664
  }
1520
1665
  return element;
1521
1666
  }
1522
- async function generateRecordXml(records, config, transform) {
1667
+ async function generateRecordXml(records, config, transform, excludeFields = []) {
1523
1668
  const files = [];
1524
1669
  for (const record of records) {
1525
1670
  const recordBuilder = (0, sdk_build_core_1.unloadBuilder)({ scope: config.scope, scopeId: config.scopeId, table: record.getTable() });
@@ -1528,6 +1673,7 @@ async function generateRecordXml(records, config, transform) {
1528
1673
  record
1529
1674
  .entries()
1530
1675
  .sort(([a], [b]) => a.localeCompare(b))
1676
+ .filter(([prop]) => excludeFields.length === 0 || !excludeFields.includes(prop))
1531
1677
  .forEach(([prop, shape]) => builder.field(prop, shape));
1532
1678
  files.push({
1533
1679
  source: record,