@servicenow/sdk-build-plugins 4.0.1 → 4.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.
Files changed (111) hide show
  1. package/dist/acl-plugin.js +23 -16
  2. package/dist/acl-plugin.js.map +1 -1
  3. package/dist/application-menu-plugin.js +15 -14
  4. package/dist/application-menu-plugin.js.map +1 -1
  5. package/dist/atf/test-plugin.js +37 -34
  6. package/dist/atf/test-plugin.js.map +1 -1
  7. package/dist/basic-syntax-plugin.js +50 -1
  8. package/dist/basic-syntax-plugin.js.map +1 -1
  9. package/dist/business-rule-plugin.js +12 -10
  10. package/dist/business-rule-plugin.js.map +1 -1
  11. package/dist/claims-plugin.d.ts +3 -0
  12. package/dist/claims-plugin.js +95 -0
  13. package/dist/claims-plugin.js.map +1 -0
  14. package/dist/client-script-plugin.js +1 -1
  15. package/dist/client-script-plugin.js.map +1 -1
  16. package/dist/column/column-to-record.d.ts +3 -3
  17. package/dist/column/column-to-record.js +17 -16
  18. package/dist/column/column-to-record.js.map +1 -1
  19. package/dist/column-plugin.js +86 -8
  20. package/dist/column-plugin.js.map +1 -1
  21. package/dist/cross-scope-privilege-plugin.js +17 -3
  22. package/dist/cross-scope-privilege-plugin.js.map +1 -1
  23. package/dist/html-import-plugin.js +8 -1
  24. package/dist/html-import-plugin.js.map +1 -1
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +3 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/json-plugin.d.ts +7 -2
  29. package/dist/json-plugin.js +28 -12
  30. package/dist/json-plugin.js.map +1 -1
  31. package/dist/list-plugin.js +29 -17
  32. package/dist/list-plugin.js.map +1 -1
  33. package/dist/now-config-plugin.js +14 -5
  34. package/dist/now-config-plugin.js.map +1 -1
  35. package/dist/now-include-plugin.d.ts +6 -7
  36. package/dist/now-include-plugin.js +59 -26
  37. package/dist/now-include-plugin.js.map +1 -1
  38. package/dist/now-ref-plugin.js +1 -1
  39. package/dist/now-ref-plugin.js.map +1 -1
  40. package/dist/package-json-plugin.js +5 -7
  41. package/dist/package-json-plugin.js.map +1 -1
  42. package/dist/property-plugin.js +1 -1
  43. package/dist/property-plugin.js.map +1 -1
  44. package/dist/record-plugin.js +23 -9
  45. package/dist/record-plugin.js.map +1 -1
  46. package/dist/repack/index.d.ts +2 -0
  47. package/dist/repack/index.js +8 -0
  48. package/dist/repack/index.js.map +1 -1
  49. package/dist/rest-api-plugin.js +12 -12
  50. package/dist/rest-api-plugin.js.map +1 -1
  51. package/dist/role-plugin.js +18 -16
  52. package/dist/role-plugin.js.map +1 -1
  53. package/dist/script-action-plugin.js +1 -1
  54. package/dist/script-action-plugin.js.map +1 -1
  55. package/dist/script-include-plugin.js +6 -4
  56. package/dist/script-include-plugin.js.map +1 -1
  57. package/dist/server-module-plugin/index.d.ts +3 -1
  58. package/dist/server-module-plugin/index.js +110 -28
  59. package/dist/server-module-plugin/index.js.map +1 -1
  60. package/dist/service-portal/angular-provider-plugin.js +3 -3
  61. package/dist/service-portal/angular-provider-plugin.js.map +1 -1
  62. package/dist/service-portal/dependency-plugin.js +9 -12
  63. package/dist/service-portal/dependency-plugin.js.map +1 -1
  64. package/dist/service-portal/widget-plugin.js +8 -8
  65. package/dist/service-portal/widget-plugin.js.map +1 -1
  66. package/dist/static-content-plugin.d.ts +2 -0
  67. package/dist/static-content-plugin.js +16 -13
  68. package/dist/static-content-plugin.js.map +1 -1
  69. package/dist/table-plugin.js +55 -33
  70. package/dist/table-plugin.js.map +1 -1
  71. package/dist/ui-action-plugin.js +29 -19
  72. package/dist/ui-action-plugin.js.map +1 -1
  73. package/dist/ui-page-plugin.js +6 -3
  74. package/dist/ui-page-plugin.js.map +1 -1
  75. package/dist/user-preference-plugin.js +2 -2
  76. package/dist/user-preference-plugin.js.map +1 -1
  77. package/package.json +5 -5
  78. package/src/acl-plugin.ts +31 -27
  79. package/src/application-menu-plugin.ts +39 -39
  80. package/src/atf/test-plugin.ts +82 -81
  81. package/src/basic-syntax-plugin.ts +54 -1
  82. package/src/business-rule-plugin.ts +74 -73
  83. package/src/claims-plugin.ts +116 -0
  84. package/src/client-script-plugin.ts +1 -1
  85. package/src/column/column-to-record.ts +59 -53
  86. package/src/column-plugin.ts +93 -8
  87. package/src/cross-scope-privilege-plugin.ts +18 -3
  88. package/src/html-import-plugin.ts +12 -2
  89. package/src/index.ts +2 -1
  90. package/src/json-plugin.ts +35 -15
  91. package/src/list-plugin.ts +39 -30
  92. package/src/now-config-plugin.ts +19 -8
  93. package/src/now-include-plugin.ts +64 -30
  94. package/src/now-ref-plugin.ts +1 -1
  95. package/src/package-json-plugin.ts +7 -6
  96. package/src/property-plugin.ts +1 -1
  97. package/src/record-plugin.ts +25 -9
  98. package/src/repack/index.ts +14 -0
  99. package/src/rest-api-plugin.ts +15 -15
  100. package/src/role-plugin.ts +15 -15
  101. package/src/script-action-plugin.ts +1 -1
  102. package/src/script-include-plugin.ts +7 -4
  103. package/src/server-module-plugin/index.ts +158 -43
  104. package/src/service-portal/angular-provider-plugin.ts +12 -10
  105. package/src/service-portal/dependency-plugin.ts +12 -13
  106. package/src/service-portal/widget-plugin.ts +36 -30
  107. package/src/static-content-plugin.ts +12 -10
  108. package/src/table-plugin.ts +71 -56
  109. package/src/ui-action-plugin.ts +49 -33
  110. package/src/ui-page-plugin.ts +6 -3
  111. package/src/user-preference-plugin.ts +2 -2
@@ -1,6 +1,6 @@
1
1
  import MD5 from 'md5.js'
2
2
  import * as mime from 'mime-types'
3
- import { Shape, Plugin, type Record, unloadBuilder, gzipSync } from '@servicenow/sdk-build-core'
3
+ import { Shape, Plugin, type Record, unloadBuilder, gzipSync, type RecordContext } from '@servicenow/sdk-build-core'
4
4
  import { path as pathModule } from '@servicenow/sdk-build-core'
5
5
  import { INVALID_XML_CHARACTERS } from './utils'
6
6
 
@@ -8,15 +8,15 @@ import { INVALID_XML_CHARACTERS } from './utils'
8
8
  // https://code.devsnc.com/dev/sn-tectonic/blob/b3ab42ce742158cb5a0d00efd540b97eeafcbdd7/core/metadata-transform-san-diego/utils/index.js#L66
9
9
  const MAX_INLINE_CONTENT_SIZE = 4194304
10
10
  // https://code.devsnc.com/dev/sn-tectonic/blob/b3ab42ce742158cb5a0d00efd540b97eeafcbdd7/core/metadata-transform-san-diego/attachment/index.js#L7
11
- const CHUNK_SIZE = 933336
11
+ export const CHUNK_SIZE = 933336
12
12
 
13
13
  const base64 = (data: Uint8Array | Buffer | string): string => Buffer.from(data).toString('base64')
14
14
 
15
- const chunkData = (data: string): string[] => {
15
+ export const chunkData = (data: string): string[] => {
16
16
  const numChunks = Math.ceil(data.length / CHUNK_SIZE)
17
17
  const chunks: string[] = new Array(numChunks)
18
18
  for (let chunk = 0, offset = 0; chunk < numChunks; chunk += 1, offset += CHUNK_SIZE) {
19
- chunks[chunk] = data.substring(offset, CHUNK_SIZE)
19
+ chunks[chunk] = data.substring(offset, offset + CHUNK_SIZE)
20
20
  }
21
21
 
22
22
  return chunks
@@ -36,10 +36,11 @@ function validateCdata(data: string): boolean {
36
36
  return true
37
37
  }
38
38
 
39
- const multipleRecordsToFile = (mainRecord, { config }) => {
39
+ const multipleRecordsToFile = async (mainRecord: Record, { config, transform }: RecordContext) => {
40
40
  const recordBuilder = unloadBuilder(config)
41
41
  for (const record of mainRecord.flat()) {
42
- const builder = recordBuilder.record(record)
42
+ const updateName = await transform.getUpdateName(record)
43
+ const builder = recordBuilder.record(record, updateName)
43
44
 
44
45
  record
45
46
  .entries()
@@ -49,6 +50,7 @@ const multipleRecordsToFile = (mainRecord, { config }) => {
49
50
  return {
50
51
  success: true,
51
52
  value: {
53
+ source: mainRecord,
52
54
  name: `${mainRecord.getTable()}_${mainRecord.getId().getValue()}.xml`,
53
55
  category: mainRecord.getInstallCategory(),
54
56
  content: recordBuilder.end(),
@@ -104,7 +106,7 @@ export const StaticContentPlugin = Plugin.create({
104
106
  {
105
107
  entryPoint: true,
106
108
  matcher: (path, { config, project }) => project.isInDir(config.staticContentDir, path),
107
- toRecord(file, { project, config, factory, logger, fs }) {
109
+ async toRecord(file, { project, config, factory, logger, fs }) {
108
110
  const { path } = file
109
111
  const relativePath = pathModule.relative(project.resolvePath(config.staticContentDir), path)
110
112
  const ext = pathModule.extname(relativePath)
@@ -187,7 +189,7 @@ export const StaticContentPlugin = Plugin.create({
187
189
  logSkippedWithReason(`Unsupported content type ${mimeType}.`)
188
190
  }
189
191
  if (tableName && assetName) {
190
- const mainRecord = factory.createRecord({
192
+ const mainRecord = await factory.createRecord({
191
193
  source: file,
192
194
  table: tableName,
193
195
  explicitId: assetName,
@@ -199,7 +201,7 @@ export const StaticContentPlugin = Plugin.create({
199
201
  if (useAttachment) {
200
202
  const attachmentRecordId = generateId(mainRecordId, 'sys_attachment', assetName)
201
203
  const zipEncodedContent = gzipSync(rawFileContent, { mtime: 0 })
202
- const attachmentRecord = factory.createRecord({
204
+ const attachmentRecord = await factory.createRecord({
203
205
  source: file,
204
206
  table: 'sys_attachment',
205
207
  properties: {
@@ -225,7 +227,7 @@ export const StaticContentPlugin = Plugin.create({
225
227
  for (let i = 0; i < chunks.length; i++) {
226
228
  const sysId = generateId(mainRecordId, 'sys_attachment_doc', assetName, i)
227
229
  attachmentRecords.push(
228
- factory.createRecord({
230
+ await factory.createRecord({
229
231
  source: file,
230
232
  table: 'sys_attachment_doc',
231
233
  properties: {
@@ -12,6 +12,7 @@ import {
12
12
  VariableStatementShape,
13
13
  IdentifierShape,
14
14
  type ObjectShape,
15
+ type Transform,
15
16
  } from '@servicenow/sdk-build-core'
16
17
  import { XMLParser } from 'fast-xml-parser'
17
18
  import { z } from 'zod'
@@ -363,7 +364,7 @@ export const TablePlugin = Plugin.create({
363
364
  files: [
364
365
  {
365
366
  matcher: /\.xml$/,
366
- toRecord(file, { factory }) {
367
+ async toRecord(file, { factory }) {
367
368
  const xml = new XMLParser({
368
369
  ignoreAttributes: false,
369
370
  alwaysCreateTextNode: true,
@@ -380,24 +381,26 @@ export const TablePlugin = Plugin.create({
380
381
  }
381
382
 
382
383
  const recordDefs = tableDefToRecordProperties(tableDef)
383
- const [sysDbRecord, ...relatedRecords] = (
384
- [
385
- ['sysDbObject', 'sys_db_object'],
386
- ['sysDictionary', 'sys_dictionary'],
387
- ['sysChoice', 'sys_choice'],
388
- ['sysIndex', 'sys_index'],
389
- ['sysDocumentation', 'sys_documentation'],
390
- ] as const
391
- ).flatMap(([key, table]) => {
392
- return [recordDefs[key]].flat().map((rec) =>
393
- factory.createRecord({
394
- source: file,
395
- table,
396
- properties: filterUndefinedProperties(rec),
397
- })
398
- )
399
- })
384
+ const records: Record[] = []
385
+ for (const [key, table] of [
386
+ ['sysDbObject', 'sys_db_object'],
387
+ ['sysDictionary', 'sys_dictionary'],
388
+ ['sysChoice', 'sys_choice'],
389
+ ['sysIndex', 'sys_index'],
390
+ ['sysDocumentation', 'sys_documentation'],
391
+ ] as const) {
392
+ for (const rec of [recordDefs[key]].flat()) {
393
+ records.push(
394
+ await factory.createRecord({
395
+ source: file,
396
+ table,
397
+ properties: filterUndefinedProperties(rec),
398
+ })
399
+ )
400
+ }
401
+ }
400
402
 
403
+ const [sysDbRecord, ...relatedRecords] = records
401
404
  return {
402
405
  success: true,
403
406
  value: sysDbRecord!.with(...relatedRecords),
@@ -684,7 +687,7 @@ export const TablePlugin = Plugin.create({
684
687
  }),
685
688
  }
686
689
  },
687
- toFile(record, { descendants, config }) {
690
+ async toFile(record, { descendants, config, transform }) {
688
691
  if (config.tableOutputFormat !== 'bootstrap' || record.isDeleted()) {
689
692
  // Defer to record plugin
690
693
  return { success: false }
@@ -861,31 +864,27 @@ export const TablePlugin = Plugin.create({
861
864
  ]
862
865
  ).end({ prettyPrint: true })
863
866
 
864
- const documentationFiles = generateRecordXml(
867
+ const documentationFiles = await generateRecordXml(
865
868
  documentation.filter(
866
869
  (doc) => !isDefaultDocumentation(doc.get('element')?.toString().getValue(), [doc])
867
870
  ),
868
871
  config,
869
- (doc) =>
870
- `sys_documentation_${tableName}${doc.get('element').isDefined() ? `_${doc.get('element').asString().getValue()}` : ''}_${doc.get('language').isDefined() ? doc.get('language').asString().getValue() : 'en'}.xml`
872
+ transform
871
873
  )
872
874
 
873
- const licensingFiles = generateRecordXml(
875
+ const licensingFiles = await generateRecordXml(
874
876
  licensing.filter((licensing) => !isDefaultLicenseConfig(tableName, licensing)),
875
877
  config,
876
- (record) => `ua_table_licensing_config_${record.getId().getValue()}.xml`
878
+ transform
877
879
  )
878
880
 
879
- const autoNumberFiles = generateRecordXml(
880
- autoNumber,
881
- config,
882
- (record) => `sys_number_${record.getId().getValue()}.xml`
883
- )
881
+ const autoNumberFiles = await generateRecordXml(autoNumber, config, transform)
884
882
 
885
883
  return {
886
884
  success: true,
887
885
  value: [
888
886
  {
887
+ source: record,
889
888
  name: `${tableName}.xml`,
890
889
  category: 'dictionary',
891
890
  content: tableXml,
@@ -899,15 +898,24 @@ export const TablePlugin = Plugin.create({
899
898
  },
900
899
  sys_dictionary: {
901
900
  coalesce: ['name', 'element'],
901
+ getUpdateName: (record) => ({
902
+ success: true,
903
+ value: `sys_dictionary_${record.get('name').getValue()}_${record.get('element').getValue() || 'null'}`,
904
+ }),
902
905
  },
903
906
  sys_documentation: {
904
907
  coalesce: ['name', 'element', 'language'],
908
+ getUpdateName: (record) => ({
909
+ success: true,
910
+ value: `sys_documentation_${record.get('name').getValue()}_${record.get('element').ifDefined()?.getValue() || ''}_${record.get('language').ifDefined()?.getValue() || 'en'}`,
911
+ }),
905
912
  },
906
913
  ua_table_licensing_config: {
907
914
  coalesce: ['name'],
908
915
  },
909
916
  sys_index: {
910
917
  coalesce: ['logical_table_name', 'col_name_string'],
918
+ // TODO: Need to implement getUpdateName() but the platform logic is pretty wild. Will take some effort.
911
919
  },
912
920
  sys_number: {
913
921
  coalesce: ['category', 'prefix'],
@@ -1010,7 +1018,7 @@ export const TablePlugin = Plugin.create({
1010
1018
  : (indexObject['element'] as string)
1011
1019
 
1012
1020
  relatedRecords.push(
1013
- factory.createRecord({
1021
+ await factory.createRecord({
1014
1022
  source: statement ?? callExpression,
1015
1023
  table: 'sys_index',
1016
1024
  properties: {
@@ -1028,7 +1036,7 @@ export const TablePlugin = Plugin.create({
1028
1036
  if (table.get('licensingConfig').isObject()) {
1029
1037
  const licenseObj = table.get('licensingConfig').asObject().withAliasedKeys(licensingAliases)
1030
1038
  generateDeprecatedDiagnostics(licenseObj, diagnostics)
1031
- const licenseRecord = factory.createRecord({
1039
+ const licenseRecord = await factory.createRecord({
1032
1040
  source: statement ?? callExpression,
1033
1041
  table: 'ua_table_licensing_config',
1034
1042
  properties: licenseObj.transform(({ $ }) => ({
@@ -1056,7 +1064,7 @@ export const TablePlugin = Plugin.create({
1056
1064
  relatedRecords.push(licenseRecord)
1057
1065
  } else {
1058
1066
  relatedRecords.push(
1059
- factory.createRecord({
1067
+ await factory.createRecord({
1060
1068
  source: statement ?? callExpression,
1061
1069
  table: 'ua_table_licensing_config',
1062
1070
  properties: {
@@ -1092,7 +1100,7 @@ export const TablePlugin = Plugin.create({
1092
1100
  languages.add(language)
1093
1101
  }
1094
1102
  relatedRecords.push(
1095
- factory.createRecord({
1103
+ await factory.createRecord({
1096
1104
  source: statement ?? callExpression,
1097
1105
  table: 'sys_documentation',
1098
1106
  properties: docObject.transform(({ $ }) => ({
@@ -1111,7 +1119,7 @@ export const TablePlugin = Plugin.create({
1111
1119
  }
1112
1120
  } else {
1113
1121
  relatedRecords.push(
1114
- factory.createRecord({
1122
+ await factory.createRecord({
1115
1123
  source: statement ?? callExpression,
1116
1124
  table: 'sys_documentation',
1117
1125
  properties: {
@@ -1131,7 +1139,7 @@ export const TablePlugin = Plugin.create({
1131
1139
  let numberRef: RecordId | undefined
1132
1140
  if (table.get('autoNumber').isObject()) {
1133
1141
  const autoNumber = table.get('autoNumber').asObject().withAliasedKeys(autoNumberAliases)
1134
- const sysNumberRecord = factory.createRecord({
1142
+ const sysNumberRecord = await factory.createRecord({
1135
1143
  source: statement ?? callExpression,
1136
1144
  table: 'sys_number',
1137
1145
  properties: autoNumber.transform(({ $ }) => ({
@@ -1147,7 +1155,7 @@ export const TablePlugin = Plugin.create({
1147
1155
 
1148
1156
  // sys_dictionary (collection)
1149
1157
  relatedRecords.push(
1150
- factory.createRecord({
1158
+ await factory.createRecord({
1151
1159
  source: statement ?? callExpression,
1152
1160
  table: 'sys_dictionary',
1153
1161
  properties: table.transform(({ $ }) => ({
@@ -1177,8 +1185,17 @@ export const TablePlugin = Plugin.create({
1177
1185
  .some((action) => action.isString() && action.getValue() === actionName)
1178
1186
  }
1179
1187
 
1188
+ const ext = table.get('extends')
1189
+ const parentReference = ext.isString()
1190
+ ? await factory.createReference({
1191
+ source: ext,
1192
+ table: 'sys_db_object',
1193
+ keys: { name: ext },
1194
+ })
1195
+ : ext.ifDefined()?.toRecordId()
1196
+
1180
1197
  // sys_db_object
1181
- const tableRecord = factory.createRecord({
1198
+ const tableRecord = await factory.createRecord({
1182
1199
  source: statement ?? callExpression,
1183
1200
  table: 'sys_db_object',
1184
1201
  properties: table.transform(({ $ }) => ({
@@ -1193,16 +1210,7 @@ export const TablePlugin = Plugin.create({
1193
1210
  (callerAccess.ifString()?.getValue() ?? 'none') as 'none' | 'tracking' | 'restricted'
1194
1211
  )
1195
1212
  ),
1196
- super_class: $.from('extends').map(
1197
- (v) =>
1198
- v.ifString()?.pipe((parent) =>
1199
- factory.createReference({
1200
- source: parent,
1201
- table: 'sys_db_object',
1202
- keys: { name: parent.getValue() },
1203
- })
1204
- ) ?? v.ifDefined()?.toRecordId()
1205
- ),
1213
+ super_class: $.val(parentReference),
1206
1214
  read_access: $.from('actions')
1207
1215
  .map((actions) => hasAction('read', actions))
1208
1216
  .def(true),
@@ -1658,24 +1666,31 @@ function createElement(name: string, attributes: [string, string][] = [], childr
1658
1666
  return element
1659
1667
  }
1660
1668
 
1661
- function generateRecordXml(
1669
+ async function generateRecordXml(
1662
1670
  records: Record[],
1663
1671
  config: { scope: string; scopeId: string },
1664
- getFileName: (record: Record) => string
1665
- ): OutputFile[] {
1666
- return records.map((record) => {
1672
+ transform: Transform
1673
+ ): Promise<OutputFile[]> {
1674
+ const files: OutputFile[] = []
1675
+ for (const record of records) {
1667
1676
  const recordBuilder = unloadBuilder({ scope: config.scope, scopeId: config.scopeId })
1668
- const builder = recordBuilder.record(record)
1677
+ const updateName = await transform.getUpdateName(record)
1678
+ const builder = recordBuilder.record(record, updateName)
1679
+
1669
1680
  record
1670
1681
  .entries()
1671
1682
  .sort(([a], [b]) => a.localeCompare(b))
1672
1683
  .forEach(([prop, shape]) => builder.field(prop, shape))
1673
- return {
1674
- name: getFileName(record),
1684
+
1685
+ files.push({
1686
+ source: record,
1687
+ name: `${updateName}.xml`,
1675
1688
  category: record.getInstallCategory(),
1676
1689
  content: recordBuilder.end(),
1677
- }
1678
- })
1690
+ })
1691
+ }
1692
+
1693
+ return files
1679
1694
  }
1680
1695
 
1681
1696
  export function isDefaultLicenseConfig(tableName: string, licenseRecord: Record): boolean {
@@ -1,4 +1,11 @@
1
- import { CallExpressionShape, Plugin, type RecordId, type Shape, type StringShape } from '@servicenow/sdk-build-core'
1
+ import {
2
+ CallExpressionShape,
3
+ Plugin,
4
+ type Record,
5
+ type RecordId,
6
+ type Shape,
7
+ type StringShape,
8
+ } from '@servicenow/sdk-build-core'
2
9
  import { NowIdShape } from './now-id-plugin'
3
10
  import { ModuleFunctionShape } from './server-module-plugin'
4
11
 
@@ -186,7 +193,7 @@ export const UiActionPlugin = Plugin.create({
186
193
  const arg = callExpression.getArgument(0).asObject()
187
194
  const isClient = arg.get(['client', 'isClient'])
188
195
 
189
- const uiAction = factory.createRecord({
196
+ const uiAction = await factory.createRecord({
190
197
  source: callExpression,
191
198
  table: 'sys_ui_action',
192
199
  explicitId: arg.get('$id'),
@@ -197,7 +204,7 @@ export const UiActionPlugin = Plugin.create({
197
204
  comments: $.def(''),
198
205
  active: $.def(true),
199
206
  client: $.val(isClient),
200
- onClick: $.val(arg.get(['client', 'onClick'])),
207
+ onclick: $.val(arg.get(['client', 'onClick'])),
201
208
  messages: $.val(
202
209
  arg.get('messages')?.isArray()
203
210
  ? arg.get('messages').asArray().getValue().join('\n')
@@ -263,60 +270,69 @@ export const UiActionPlugin = Plugin.create({
263
270
  )
264
271
  }
265
272
  })
266
- const uiActioneViews = [
267
- ...includeInViews.map((view) =>
268
- factory.createRecord({
273
+
274
+ const uiActionViews: Record[] = []
275
+ for (const view of includeInViews) {
276
+ uiActionViews.push(
277
+ await factory.createRecord({
269
278
  source: callExpression,
270
279
  table: 'sys_ui_action_view',
271
280
  properties: {
272
281
  sys_ui_action: uiAction.getId(),
273
282
  visibility: 'include',
274
- sys_ui_view: factory.createReference({
283
+ sys_ui_view: await factory.createReference({
275
284
  source: view,
276
285
  table: 'sys_ui_view',
277
286
  keys: { name: view },
278
287
  }),
279
288
  },
280
289
  })
281
- ),
282
- ...excludeFromViews.map((view) =>
283
- factory.createRecord({
290
+ )
291
+ }
292
+
293
+ for (const view of excludeFromViews) {
294
+ uiActionViews.push(
295
+ await factory.createRecord({
284
296
  source: callExpression,
285
297
  table: 'sys_ui_action_view',
286
298
  properties: {
287
299
  sys_ui_action: uiAction.getId(),
288
300
  visibility: 'exclude',
289
- sys_ui_view: factory.createReference({
301
+ sys_ui_view: await factory.createReference({
290
302
  source: view,
291
303
  table: 'sys_ui_view',
292
304
  keys: { name: view },
293
305
  }),
294
306
  },
295
307
  })
296
- ),
297
- ]
308
+ )
309
+ }
310
+
311
+ const roleRecords: Record[] = []
312
+ for (const role of roles) {
313
+ const roleReference = role.isString()
314
+ ? await factory.createReference({
315
+ source: role,
316
+ table: 'sys_user_role',
317
+ keys: { name: role },
318
+ })
319
+ : role
320
+
321
+ roleRecords.push(
322
+ await factory.createRecord({
323
+ source: callExpression,
324
+ table: 'sys_ui_action_role',
325
+ properties: {
326
+ sys_ui_action: uiAction.getId(),
327
+ sys_user_role: roleReference,
328
+ },
329
+ })
330
+ )
331
+ }
332
+
298
333
  return {
299
334
  success: true,
300
- value: uiAction.with(
301
- ...roles.map((role) =>
302
- factory.createRecord({
303
- source: callExpression,
304
- table: 'sys_ui_action_role',
305
- properties: {
306
- sys_ui_action: uiAction.getId(),
307
- sys_user_role:
308
- role.ifString()?.pipe((roleName) =>
309
- factory.createReference({
310
- source: roleName,
311
- table: 'sys_user_role',
312
- keys: { name: roleName },
313
- })
314
- ) ?? role,
315
- },
316
- })
317
- ),
318
- ...uiActioneViews
319
- ),
335
+ value: uiAction.with(...roleRecords, ...uiActionViews),
320
336
  }
321
337
  },
322
338
  },
@@ -42,7 +42,9 @@ const nowUxGlobals = (themeId: string = POLARIS_APPSHELL_THEME_ID) => {
42
42
  window.NOW = {};
43
43
  window.NOW.user = {};
44
44
  window.NOW.batch_glide_ajax_requests = false;
45
- window.g_ck = "$[gs.getSession().getSessionToken()]";
45
+ window.NOW.isUsingPolaris = true;
46
+ window.NOW.exclude_dark_theme = "false";
47
+ window.g_ck = "$[gs.getSession().getSessionToken() || gs.getSessionToken()]";
46
48
  </script>
47
49
  <!-- Include ServiceNow's required scripts -->
48
50
  <g:requires name="scripts/doctype/functions_bootstrap14.js" />
@@ -53,7 +55,8 @@ window.g_ck = "$[gs.getSession().getSessionToken()]";
53
55
  <g:requires name="scripts/classes/GlideUser.js" />
54
56
  <g2:client_script type="user" />
55
57
  <link rel="preload" href="/uxasset/set-cache-buster/$[UxFrameworkScriptables.getFlushTimestamp()].js" as="script"></link>
56
- <link data-source-id="glide-theme" rel="stylesheet" href="/$uxappimmutables.do?sysparm_request_type=ux_theme$[AMP]sysparm_app_sys_id=${themeId}$[AMP]uxpcb=$[UxFrameworkScriptables.getFlushTimestamp()]"></link>
58
+ <g:requires name="scripts/polaris_theme_refresh_observer.js" />
59
+ <link data-source-id="glide-theme" id="polarisberg_theme_variables" rel="stylesheet" href="/$uxappimmutables.do?sysparm_request_type=ux_theme$[AMP]sysparm_app_sys_id=${themeId}$[AMP]uxpcb=$[sn_ui.PolarisUI.getThemeVariableCssCacheKey()]"></link>
57
60
  <script type="module" src="/uxasset/externals/@devsnc/library-uxf/index.jsdbx"></script>
58
61
  <!-- @sdk:now-ux-globals -->
59
62
  `)
@@ -146,7 +149,7 @@ export const UiPagePlugin = Plugin.create({
146
149
 
147
150
  return {
148
151
  success: true,
149
- value: factory.createRecord({
152
+ value: await factory.createRecord({
150
153
  source: callExpression,
151
154
  table: 'sys_ui_page',
152
155
  explicitId: arg.get('$id'),
@@ -40,7 +40,7 @@ export const UserPreferencePlugin = Plugin.create({
40
40
  {
41
41
  shape: CallExpressionShape,
42
42
  fileTypes: ['fluent'],
43
- toRecord(callExpression, { factory }) {
43
+ async toRecord(callExpression, { factory }) {
44
44
  if (callExpression.getCallee() !== 'UserPreference') {
45
45
  return { success: false }
46
46
  }
@@ -49,7 +49,7 @@ export const UserPreferencePlugin = Plugin.create({
49
49
 
50
50
  return {
51
51
  success: true,
52
- value: factory.createRecord({
52
+ value: await factory.createRecord({
53
53
  source: callExpression,
54
54
  table: 'sys_user_preference',
55
55
  explicitId: pref.get('$id'),