@servicenow/sdk-build-plugins 4.4.1 → 4.6.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 (337) hide show
  1. package/dist/acl-plugin.js +54 -4
  2. package/dist/acl-plugin.js.map +1 -1
  3. package/dist/applicability-plugin.js +2 -0
  4. package/dist/applicability-plugin.js.map +1 -1
  5. package/dist/application-menu-plugin.js +2 -0
  6. package/dist/application-menu-plugin.js.map +1 -1
  7. package/dist/arrow-function-plugin.d.ts +6 -1
  8. package/dist/arrow-function-plugin.js +105 -12
  9. package/dist/arrow-function-plugin.js.map +1 -1
  10. package/dist/atf/test-plugin.js +2 -0
  11. package/dist/atf/test-plugin.js.map +1 -1
  12. package/dist/basic-syntax-plugin.js +20 -0
  13. package/dist/basic-syntax-plugin.js.map +1 -1
  14. package/dist/call-expression-plugin.js +1 -0
  15. package/dist/call-expression-plugin.js.map +1 -1
  16. package/dist/claims-plugin.js +1 -0
  17. package/dist/claims-plugin.js.map +1 -1
  18. package/dist/client-script-plugin.js +1 -0
  19. package/dist/client-script-plugin.js.map +1 -1
  20. package/dist/column-plugin.js +4 -7
  21. package/dist/column-plugin.js.map +1 -1
  22. package/dist/cross-scope-privilege-plugin.js +1 -0
  23. package/dist/cross-scope-privilege-plugin.js.map +1 -1
  24. package/dist/dashboard/dashboard-plugin.js +2 -0
  25. package/dist/dashboard/dashboard-plugin.js.map +1 -1
  26. package/dist/data-plugin.js +1 -0
  27. package/dist/data-plugin.js.map +1 -1
  28. package/dist/email-notification-plugin.js +9 -13
  29. package/dist/email-notification-plugin.js.map +1 -1
  30. package/dist/flow/constants/flow-plugin-constants.d.ts +1 -1
  31. package/dist/flow/constants/flow-plugin-constants.js +1 -1
  32. package/dist/flow/constants/flow-plugin-constants.js.map +1 -1
  33. package/dist/flow/flow-logic/flow-logic-diagnostics.js +5 -5
  34. package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -1
  35. package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +82 -2
  36. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +48 -40
  37. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -1
  38. package/dist/flow/flow-logic/flow-logic-plugin.js +1 -0
  39. package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -1
  40. package/dist/flow/plugins/approval-rules-plugin.js +1 -0
  41. package/dist/flow/plugins/approval-rules-plugin.js.map +1 -1
  42. package/dist/flow/plugins/flow-action-definition-plugin.js +1232 -55
  43. package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
  44. package/dist/flow/plugins/flow-data-pill-plugin.js +6 -2
  45. package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -1
  46. package/dist/flow/plugins/flow-definition-plugin.js +23 -44
  47. package/dist/flow/plugins/flow-definition-plugin.js.map +1 -1
  48. package/dist/flow/plugins/flow-diagnostics-plugin.d.ts +2 -2
  49. package/dist/flow/plugins/flow-diagnostics-plugin.js +3 -2
  50. package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -1
  51. package/dist/flow/plugins/flow-instance-plugin.js +136 -34
  52. package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
  53. package/dist/flow/plugins/flow-trigger-instance-plugin.js +1 -0
  54. package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -1
  55. package/dist/flow/plugins/inline-script-plugin.js +1 -0
  56. package/dist/flow/plugins/inline-script-plugin.js.map +1 -1
  57. package/dist/flow/plugins/step-definition-plugin.js +4 -2
  58. package/dist/flow/plugins/step-definition-plugin.js.map +1 -1
  59. package/dist/flow/plugins/step-instance-plugin.d.ts +9 -1
  60. package/dist/flow/plugins/step-instance-plugin.js +649 -135
  61. package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
  62. package/dist/flow/plugins/trigger-plugin.js +2 -0
  63. package/dist/flow/plugins/trigger-plugin.js.map +1 -1
  64. package/dist/flow/plugins/wfa-datapill-plugin.js +21 -5
  65. package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -1
  66. package/dist/flow/post-install.d.ts +2 -0
  67. package/dist/flow/post-install.js +59 -0
  68. package/dist/flow/post-install.js.map +1 -0
  69. package/dist/flow/utils/complex-object-resolver.js +4 -1
  70. package/dist/flow/utils/complex-object-resolver.js.map +1 -1
  71. package/dist/flow/utils/complex-objects.js +5 -3
  72. package/dist/flow/utils/complex-objects.js.map +1 -1
  73. package/dist/flow/utils/flow-constants.d.ts +90 -2
  74. package/dist/flow/utils/flow-constants.js +430 -7
  75. package/dist/flow/utils/flow-constants.js.map +1 -1
  76. package/dist/flow/utils/flow-io-to-record.d.ts +1 -1
  77. package/dist/flow/utils/flow-io-to-record.js +37 -16
  78. package/dist/flow/utils/flow-io-to-record.js.map +1 -1
  79. package/dist/flow/utils/flow-shapes.js +4 -0
  80. package/dist/flow/utils/flow-shapes.js.map +1 -1
  81. package/dist/flow/utils/flow-to-xml.d.ts +3 -2
  82. package/dist/flow/utils/flow-to-xml.js +3 -4
  83. package/dist/flow/utils/flow-to-xml.js.map +1 -1
  84. package/dist/flow/utils/label-cache-parser.d.ts +9 -2
  85. package/dist/flow/utils/label-cache-parser.js +32 -4
  86. package/dist/flow/utils/label-cache-parser.js.map +1 -1
  87. package/dist/flow/utils/label-cache-processor.d.ts +5 -0
  88. package/dist/flow/utils/label-cache-processor.js +14 -2
  89. package/dist/flow/utils/label-cache-processor.js.map +1 -1
  90. package/dist/flow/utils/pill-shape-helpers.d.ts +15 -0
  91. package/dist/flow/utils/pill-shape-helpers.js +35 -0
  92. package/dist/flow/utils/pill-shape-helpers.js.map +1 -0
  93. package/dist/flow/utils/pill-string-parser.js +1 -0
  94. package/dist/flow/utils/pill-string-parser.js.map +1 -1
  95. package/dist/flow/utils/schema-to-flow-object.d.ts +6 -1
  96. package/dist/flow/utils/schema-to-flow-object.js +131 -15
  97. package/dist/flow/utils/schema-to-flow-object.js.map +1 -1
  98. package/dist/flow/utils/service-catalog.js +5 -1
  99. package/dist/flow/utils/service-catalog.js.map +1 -1
  100. package/dist/flow/utils/utils.d.ts +1 -0
  101. package/dist/flow/utils/utils.js +6 -1
  102. package/dist/flow/utils/utils.js.map +1 -1
  103. package/dist/form-plugin.d.ts +2 -0
  104. package/dist/form-plugin.js +1132 -0
  105. package/dist/form-plugin.js.map +1 -0
  106. package/dist/html-import-plugin.js +1 -0
  107. package/dist/html-import-plugin.js.map +1 -1
  108. package/dist/import-sets-plugin.js +2 -0
  109. package/dist/import-sets-plugin.js.map +1 -1
  110. package/dist/inbound-email-action-plugin.d.ts +10 -0
  111. package/dist/inbound-email-action-plugin.js +128 -0
  112. package/dist/inbound-email-action-plugin.js.map +1 -0
  113. package/dist/index.d.ts +13 -0
  114. package/dist/index.js +17 -1
  115. package/dist/index.js.map +1 -1
  116. package/dist/instance-scan-plugin.d.ts +2 -0
  117. package/dist/instance-scan-plugin.js +293 -0
  118. package/dist/instance-scan-plugin.js.map +1 -0
  119. package/dist/json-plugin.js +1 -0
  120. package/dist/json-plugin.js.map +1 -1
  121. package/dist/list-plugin.js +1 -0
  122. package/dist/list-plugin.js.map +1 -1
  123. package/dist/now-attach-plugin.js +1 -0
  124. package/dist/now-attach-plugin.js.map +1 -1
  125. package/dist/now-config-plugin.js +659 -51
  126. package/dist/now-config-plugin.js.map +1 -1
  127. package/dist/now-id-plugin.js +1 -0
  128. package/dist/now-id-plugin.js.map +1 -1
  129. package/dist/now-include-plugin.js +1 -0
  130. package/dist/now-include-plugin.js.map +1 -1
  131. package/dist/now-ref-plugin.js +1 -0
  132. package/dist/now-ref-plugin.js.map +1 -1
  133. package/dist/now-unresolved-plugin.js +1 -0
  134. package/dist/now-unresolved-plugin.js.map +1 -1
  135. package/dist/package-json-plugin.js +1 -0
  136. package/dist/package-json-plugin.js.map +1 -1
  137. package/dist/property-plugin.js +3 -1
  138. package/dist/property-plugin.js.map +1 -1
  139. package/dist/record-plugin.d.ts +37 -0
  140. package/dist/record-plugin.js +47 -3
  141. package/dist/record-plugin.js.map +1 -1
  142. package/dist/repack/lint/Rules.d.ts +11 -2
  143. package/dist/repack/lint/Rules.js +160 -16
  144. package/dist/repack/lint/Rules.js.map +1 -1
  145. package/dist/repack/lint/index.d.ts +10 -5
  146. package/dist/repack/lint/index.js +76 -50
  147. package/dist/repack/lint/index.js.map +1 -1
  148. package/dist/rest-api-plugin.js +22 -1
  149. package/dist/rest-api-plugin.js.map +1 -1
  150. package/dist/role-plugin.js +1 -0
  151. package/dist/role-plugin.js.map +1 -1
  152. package/dist/schedule-script/index.d.ts +1 -0
  153. package/dist/schedule-script/index.js +18 -0
  154. package/dist/schedule-script/index.js.map +1 -0
  155. package/dist/schedule-script/scheduled-script-plugin.d.ts +2 -0
  156. package/dist/schedule-script/scheduled-script-plugin.js +556 -0
  157. package/dist/schedule-script/scheduled-script-plugin.js.map +1 -0
  158. package/dist/schedule-script/timeZoneConverter.d.ts +61 -0
  159. package/dist/schedule-script/timeZoneConverter.js +170 -0
  160. package/dist/schedule-script/timeZoneConverter.js.map +1 -0
  161. package/dist/script-action-plugin.js +2 -0
  162. package/dist/script-action-plugin.js.map +1 -1
  163. package/dist/script-include-plugin.js +2 -0
  164. package/dist/script-include-plugin.js.map +1 -1
  165. package/dist/server-module-plugin/index.js +13 -2
  166. package/dist/server-module-plugin/index.js.map +1 -1
  167. package/dist/service-catalog/catalog-clientscript-plugin.js +2 -0
  168. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -1
  169. package/dist/service-catalog/catalog-item-plugin.js +2 -0
  170. package/dist/service-catalog/catalog-item-plugin.js.map +1 -1
  171. package/dist/service-catalog/catalog-ui-policy-plugin.js +2 -0
  172. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -1
  173. package/dist/service-catalog/sc-record-producer-plugin.js +2 -0
  174. package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -1
  175. package/dist/service-catalog/service-catalog-base.d.ts +18 -18
  176. package/dist/service-catalog/service-catalog-base.js +22 -22
  177. package/dist/service-catalog/service-catalog-base.js.map +1 -1
  178. package/dist/service-catalog/service-catalog-diagnostics.d.ts +6 -0
  179. package/dist/service-catalog/service-catalog-diagnostics.js +20 -0
  180. package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -1
  181. package/dist/service-catalog/shape-to-record.js +7 -2
  182. package/dist/service-catalog/shape-to-record.js.map +1 -1
  183. package/dist/service-catalog/variable-set-plugin.js +2 -0
  184. package/dist/service-catalog/variable-set-plugin.js.map +1 -1
  185. package/dist/service-portal/angular-provider-plugin.js +2 -0
  186. package/dist/service-portal/angular-provider-plugin.js.map +1 -1
  187. package/dist/service-portal/dependency-plugin.js +5 -31
  188. package/dist/service-portal/dependency-plugin.js.map +1 -1
  189. package/dist/service-portal/header-footer-plugin.d.ts +2 -0
  190. package/dist/service-portal/header-footer-plugin.js +50 -0
  191. package/dist/service-portal/header-footer-plugin.js.map +1 -0
  192. package/dist/service-portal/menu-plugin.d.ts +2 -0
  193. package/dist/service-portal/menu-plugin.js +334 -0
  194. package/dist/service-portal/menu-plugin.js.map +1 -0
  195. package/dist/service-portal/page-plugin.d.ts +2 -0
  196. package/dist/service-portal/page-plugin.js +681 -0
  197. package/dist/service-portal/page-plugin.js.map +1 -0
  198. package/dist/service-portal/page-route-map-plugin.d.ts +2 -0
  199. package/dist/service-portal/page-route-map-plugin.js +114 -0
  200. package/dist/service-portal/page-route-map-plugin.js.map +1 -0
  201. package/dist/service-portal/portal-plugin.d.ts +2 -0
  202. package/dist/service-portal/portal-plugin.js +309 -0
  203. package/dist/service-portal/portal-plugin.js.map +1 -0
  204. package/dist/service-portal/theme-plugin.d.ts +2 -0
  205. package/dist/service-portal/theme-plugin.js +112 -0
  206. package/dist/service-portal/theme-plugin.js.map +1 -0
  207. package/dist/service-portal/utils.d.ts +46 -0
  208. package/dist/service-portal/utils.js +331 -0
  209. package/dist/service-portal/utils.js.map +1 -0
  210. package/dist/service-portal/widget-plugin.js +10 -182
  211. package/dist/service-portal/widget-plugin.js.map +1 -1
  212. package/dist/sla-plugin.js +2 -0
  213. package/dist/sla-plugin.js.map +1 -1
  214. package/dist/static-content-plugin.js +5 -0
  215. package/dist/static-content-plugin.js.map +1 -1
  216. package/dist/table-plugin.js +191 -26
  217. package/dist/table-plugin.js.map +1 -1
  218. package/dist/ui-action-plugin.js +3 -4
  219. package/dist/ui-action-plugin.js.map +1 -1
  220. package/dist/ui-page-plugin.js +101 -21
  221. package/dist/ui-page-plugin.js.map +1 -1
  222. package/dist/ui-policy-plugin.js +1 -0
  223. package/dist/ui-policy-plugin.js.map +1 -1
  224. package/dist/user-preference-plugin.js +2 -0
  225. package/dist/user-preference-plugin.js.map +1 -1
  226. package/dist/utils.d.ts +20 -2
  227. package/dist/utils.js +34 -3
  228. package/dist/utils.js.map +1 -1
  229. package/dist/ux-list-menu-config-plugin.js +2 -0
  230. package/dist/ux-list-menu-config-plugin.js.map +1 -1
  231. package/dist/view-plugin.js +9 -3
  232. package/dist/view-plugin.js.map +1 -1
  233. package/dist/workspace-plugin.js +41 -36
  234. package/dist/workspace-plugin.js.map +1 -1
  235. package/package.json +11 -11
  236. package/src/_types/eslint-community-eslint-utils.d.ts +15 -0
  237. package/src/acl-plugin.ts +97 -8
  238. package/src/applicability-plugin.ts +2 -0
  239. package/src/application-menu-plugin.ts +2 -0
  240. package/src/arrow-function-plugin.ts +128 -13
  241. package/src/atf/test-plugin.ts +2 -0
  242. package/src/basic-syntax-plugin.ts +21 -0
  243. package/src/call-expression-plugin.ts +1 -0
  244. package/src/claims-plugin.ts +1 -0
  245. package/src/client-script-plugin.ts +2 -1
  246. package/src/column-plugin.ts +4 -8
  247. package/src/cross-scope-privilege-plugin.ts +2 -1
  248. package/src/dashboard/dashboard-plugin.ts +2 -0
  249. package/src/data-plugin.ts +1 -0
  250. package/src/email-notification-plugin.ts +3 -23
  251. package/src/flow/constants/flow-plugin-constants.ts +1 -1
  252. package/src/flow/flow-logic/flow-logic-diagnostics.ts +5 -6
  253. package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +47 -45
  254. package/src/flow/flow-logic/flow-logic-plugin.ts +1 -0
  255. package/src/flow/plugins/approval-rules-plugin.ts +1 -0
  256. package/src/flow/plugins/flow-action-definition-plugin.ts +1584 -62
  257. package/src/flow/plugins/flow-data-pill-plugin.ts +6 -2
  258. package/src/flow/plugins/flow-definition-plugin.ts +22 -51
  259. package/src/flow/plugins/flow-diagnostics-plugin.ts +3 -2
  260. package/src/flow/plugins/flow-instance-plugin.ts +201 -36
  261. package/src/flow/plugins/flow-trigger-instance-plugin.ts +1 -0
  262. package/src/flow/plugins/inline-script-plugin.ts +1 -0
  263. package/src/flow/plugins/step-definition-plugin.ts +4 -2
  264. package/src/flow/plugins/step-instance-plugin.ts +772 -155
  265. package/src/flow/plugins/trigger-plugin.ts +2 -0
  266. package/src/flow/plugins/wfa-datapill-plugin.ts +26 -5
  267. package/src/flow/post-install.ts +93 -0
  268. package/src/flow/utils/complex-object-resolver.ts +4 -1
  269. package/src/flow/utils/complex-objects.ts +11 -3
  270. package/src/flow/utils/flow-constants.ts +451 -6
  271. package/src/flow/utils/flow-io-to-record.ts +43 -17
  272. package/src/flow/utils/flow-shapes.ts +4 -0
  273. package/src/flow/utils/flow-to-xml.ts +4 -4
  274. package/src/flow/utils/label-cache-parser.ts +33 -4
  275. package/src/flow/utils/label-cache-processor.ts +14 -2
  276. package/src/flow/utils/pill-shape-helpers.ts +42 -0
  277. package/src/flow/utils/pill-string-parser.ts +1 -0
  278. package/src/flow/utils/schema-to-flow-object.ts +183 -15
  279. package/src/flow/utils/service-catalog.ts +5 -2
  280. package/src/flow/utils/utils.ts +12 -1
  281. package/src/form-plugin.ts +1409 -0
  282. package/src/html-import-plugin.ts +1 -0
  283. package/src/import-sets-plugin.ts +2 -0
  284. package/src/inbound-email-action-plugin.ts +145 -0
  285. package/src/index.ts +13 -0
  286. package/src/instance-scan-plugin.ts +313 -0
  287. package/src/json-plugin.ts +1 -0
  288. package/src/list-plugin.ts +2 -1
  289. package/src/now-attach-plugin.ts +1 -0
  290. package/src/now-config-plugin.ts +833 -53
  291. package/src/now-id-plugin.ts +1 -0
  292. package/src/now-include-plugin.ts +1 -0
  293. package/src/now-ref-plugin.ts +1 -0
  294. package/src/now-unresolved-plugin.ts +1 -0
  295. package/src/package-json-plugin.ts +1 -0
  296. package/src/property-plugin.ts +6 -1
  297. package/src/record-plugin.ts +56 -6
  298. package/src/repack/lint/Rules.ts +171 -22
  299. package/src/repack/lint/index.ts +80 -56
  300. package/src/rest-api-plugin.ts +28 -2
  301. package/src/role-plugin.ts +2 -1
  302. package/src/schedule-script/index.ts +1 -0
  303. package/src/schedule-script/scheduled-script-plugin.ts +690 -0
  304. package/src/schedule-script/timeZoneConverter.ts +188 -0
  305. package/src/script-action-plugin.ts +2 -0
  306. package/src/script-include-plugin.ts +2 -0
  307. package/src/server-module-plugin/index.ts +14 -2
  308. package/src/service-catalog/catalog-clientscript-plugin.ts +2 -0
  309. package/src/service-catalog/catalog-item-plugin.ts +2 -0
  310. package/src/service-catalog/catalog-ui-policy-plugin.ts +2 -0
  311. package/src/service-catalog/sc-record-producer-plugin.ts +2 -0
  312. package/src/service-catalog/service-catalog-base.ts +22 -22
  313. package/src/service-catalog/service-catalog-diagnostics.ts +30 -0
  314. package/src/service-catalog/shape-to-record.ts +8 -2
  315. package/src/service-catalog/variable-set-plugin.ts +2 -0
  316. package/src/service-portal/angular-provider-plugin.ts +2 -0
  317. package/src/service-portal/dependency-plugin.ts +6 -53
  318. package/src/service-portal/header-footer-plugin.ts +57 -0
  319. package/src/service-portal/menu-plugin.ts +413 -0
  320. package/src/service-portal/page-plugin.ts +805 -0
  321. package/src/service-portal/page-route-map-plugin.ts +124 -0
  322. package/src/service-portal/portal-plugin.ts +342 -0
  323. package/src/service-portal/theme-plugin.ts +135 -0
  324. package/src/service-portal/utils.ts +470 -0
  325. package/src/service-portal/widget-plugin.ts +18 -224
  326. package/src/sla-plugin.ts +2 -0
  327. package/src/static-content-plugin.ts +4 -0
  328. package/src/table-plugin.ts +228 -37
  329. package/src/ui-action-plugin.ts +3 -8
  330. package/src/ui-page-plugin.ts +110 -21
  331. package/src/ui-policy-plugin.ts +2 -1
  332. package/src/user-preference-plugin.ts +2 -0
  333. package/src/utils.ts +42 -2
  334. package/src/ux-list-menu-config-plugin.ts +2 -0
  335. package/src/view-plugin.ts +11 -4
  336. package/src/workspace-plugin.ts +45 -43
  337. package/src/_types/eslint-plugin-es-x.d.ts +0 -17
@@ -0,0 +1,124 @@
1
+ import { CallExpressionShape, Plugin, type Shape } from '@servicenow/sdk-build-core'
2
+ import { NowIdShape } from '../now-id-plugin'
3
+ import { toReference, createSdkDocEntry } from '../utils'
4
+ import { getRolesString } from './utils'
5
+
6
+ function getPortalsString(portalsShape: Shape): string {
7
+ const portals = portalsShape
8
+ .ifArray()
9
+ ?.getElements()
10
+ .map((p) => {
11
+ const ref = toReference(p)
12
+ return typeof ref === 'string' ? ref : ref.getValue()
13
+ })
14
+ .filter((id) => id !== '')
15
+
16
+ if (!portals || portals.length === 0) {
17
+ return ''
18
+ }
19
+ return [...new Set(portals)].join(',')
20
+ }
21
+
22
+ export const SPPageRouteMapPlugin = Plugin.create({
23
+ name: 'SPPageRouteMapPlugin',
24
+ docs: [createSdkDocEntry('SPPageRouteMap', ['sp_page_route_map'])],
25
+ records: {
26
+ sp_page_route_map: {
27
+ coalesce: ['route_from_page', 'portals'],
28
+ toShape(record) {
29
+ const portalsStr = record.get('portals').ifString()?.getValue() ?? ''
30
+ const portalsArray = portalsStr
31
+ ? portalsStr
32
+ .split(',')
33
+ .map((p) => p.trim())
34
+ .filter((p) => p !== '')
35
+ : []
36
+
37
+ const rolesStr = record.get('roles').ifString()?.getValue() ?? ''
38
+ const rolesArray = rolesStr
39
+ ? rolesStr
40
+ .split(',')
41
+ .map((r) => r.trim())
42
+ .filter((r) => r !== '')
43
+ : []
44
+
45
+ return {
46
+ success: true,
47
+ value: new CallExpressionShape({
48
+ source: record,
49
+ callee: 'SPPageRouteMap',
50
+ args: [
51
+ record.transform(({ $ }) => {
52
+ const config: { [key: string]: typeof $ | undefined } = {
53
+ $id: $.val(NowIdShape.from(record)),
54
+ routeFromPage: $.from('route_from_page'),
55
+ routeToPage: $.from('route_to_page'),
56
+ shortDescription: $.from('short_description').def(''),
57
+ active: $.from('active').toBoolean().def(true),
58
+ order: $.from('order').toNumber().def(10),
59
+ }
60
+ if (portalsArray.length > 0) {
61
+ config['portals'] = $.val(portalsArray)
62
+ }
63
+ if (rolesArray.length > 0) {
64
+ config['roles'] = $.val(rolesArray)
65
+ }
66
+ return config
67
+ }),
68
+ ],
69
+ }),
70
+ }
71
+ },
72
+ },
73
+ },
74
+ shapes: [
75
+ {
76
+ shape: CallExpressionShape,
77
+ fileTypes: ['fluent'],
78
+ async toRecord(callExpression, { factory, diagnostics }) {
79
+ if (callExpression.getCallee() !== 'SPPageRouteMap') {
80
+ return { success: false }
81
+ }
82
+
83
+ const args = callExpression.getArgument(0).asObject()
84
+
85
+ const routeFromShape = args.get('routeFromPage')
86
+ const routeToShape = args.get('routeToPage')
87
+ const routeFromRef = toReference(routeFromShape)
88
+ const routeToRef = toReference(routeToShape)
89
+ const routeFromStr = typeof routeFromRef === 'string' ? routeFromRef : routeFromRef.getValue()
90
+ const routeToStr = typeof routeToRef === 'string' ? routeToRef : routeToRef.getValue()
91
+
92
+ if (routeFromStr !== '' && routeToStr !== '' && routeFromStr === routeToStr) {
93
+ diagnostics.error(
94
+ routeToShape.getOriginalNode(),
95
+ `Invalid SPPageRouteMap: "routeToPage" must be different from "routeFromPage".`
96
+ )
97
+ }
98
+
99
+ const portalsString = getPortalsString(args.get('portals'))
100
+ const rolesString = getRolesString(args.get('roles'), diagnostics)
101
+
102
+ const routeMapRecord = await factory.createRecord({
103
+ source: callExpression,
104
+ table: 'sp_page_route_map',
105
+ explicitId: args.get('$id'),
106
+ properties: args.transform(({ $ }) => ({
107
+ route_from_page: $.from('routeFromPage').map(toReference).def(''),
108
+ route_to_page: $.from('routeToPage').map(toReference).def(''),
109
+ short_description: $.from('shortDescription').def(''),
110
+ portals: $.val(portalsString).def(''),
111
+ roles: $.val(rolesString).def(''),
112
+ active: $.def(true),
113
+ order: $.def(10),
114
+ })),
115
+ })
116
+
117
+ return {
118
+ success: true,
119
+ value: routeMapRecord,
120
+ }
121
+ },
122
+ },
123
+ ],
124
+ })
@@ -0,0 +1,342 @@
1
+ import { Plugin, CallExpressionShape, type Record, type Shape } from '@servicenow/sdk-build-core'
2
+ import { NowIdShape } from '../now-id-plugin'
3
+ import { createSdkDocEntry } from '../utils'
4
+
5
+ function convertToNumber(value: Shape, defaultValue: number = 0): number {
6
+ if (!value || value.isUndefined() || value.ifString()?.isEmpty()) {
7
+ return defaultValue
8
+ }
9
+ return value.toNumber()?.getValue() ?? defaultValue
10
+ }
11
+
12
+ export const ServicePortalPlugin = Plugin.create({
13
+ name: 'ServicePortalPlugin',
14
+ docs: [createSdkDocEntry('ServicePortal', ['sp_portal'])],
15
+ records: {
16
+ sp_portal: {
17
+ relationships: {
18
+ m2m_sp_portal_search_source: {
19
+ descendant: true,
20
+ via: 'sp_portal',
21
+ },
22
+ m2m_sp_portal_knowledge_base: {
23
+ descendant: true,
24
+ via: 'sp_portal',
25
+ },
26
+ m2m_sp_portal_catalog: {
27
+ descendant: true,
28
+ via: 'sp_portal',
29
+ },
30
+ m2m_sp_portal_taxonomy: {
31
+ descendant: true,
32
+ via: 'sp_portal',
33
+ },
34
+ },
35
+ toShape(record, { descendants }) {
36
+ // Handle search sources
37
+ const searchSources = descendants.query('m2m_sp_portal_search_source').map((m2m) => {
38
+ return {
39
+ searchSource: m2m.get('sp_search_source'),
40
+ order: convertToNumber(m2m.get('order'), 100),
41
+ }
42
+ })
43
+
44
+ // Handle knowledge bases
45
+ const knowledgeBases = descendants
46
+ .query('m2m_sp_portal_knowledge_base')
47
+ .filter((m2m) => !m2m.get('kb_knowledge_base')?.ifString()?.isEmpty())
48
+ .map((m2m) => {
49
+ return {
50
+ knowledgeBase: m2m.get('kb_knowledge_base'),
51
+ order: convertToNumber(m2m.get('order'), 100),
52
+ active: m2m.get('active')?.isUndefined()
53
+ ? undefined
54
+ : m2m.get('active')?.toBoolean()?.getValue(),
55
+ }
56
+ })
57
+
58
+ // Handle catalogs
59
+ const catalogs = descendants
60
+ .query('m2m_sp_portal_catalog')
61
+ .filter((m2m) => !m2m.get('sc_catalog')?.ifString()?.isEmpty())
62
+ .map((m2m) => {
63
+ return {
64
+ catalog: m2m.get('sc_catalog'),
65
+ order: convertToNumber(m2m.get('order'), 100),
66
+ active: m2m.get('active')?.isUndefined()
67
+ ? undefined
68
+ : m2m.get('active')?.toBoolean()?.getValue(),
69
+ }
70
+ })
71
+
72
+ // Handle taxonomies
73
+ const taxonomies = descendants.query('m2m_sp_portal_taxonomy').map((m2m) => {
74
+ return {
75
+ taxonomy: m2m.get('taxonomy'),
76
+ order: convertToNumber(m2m.get('order'), 100),
77
+ active: m2m.get('active')?.isUndefined()
78
+ ? undefined
79
+ : m2m.get('active')?.toBoolean()?.getValue(),
80
+ }
81
+ })
82
+
83
+ const portalRecord = new CallExpressionShape({
84
+ source: record,
85
+ callee: 'ServicePortal',
86
+ args: [
87
+ record.transform(({ $ }) => ({
88
+ $id: $.val(NowIdShape.from(record)),
89
+ title: $,
90
+ urlSuffix: $.from('url_suffix').def(''),
91
+ icon: $.from('icon').def(''),
92
+ logo: $.from('logo').def(''),
93
+ logoAltText: $.from('logo_alt_text').def(''),
94
+ quickStartConfig: $.from('quick_start_config').def(''),
95
+ embeddableMacroponents: $.from('embeddable_macroponents').def(''),
96
+ communicationChannels: $.from('communication_channels').def(''),
97
+ cssVariables: $.from('css_variables').def(''),
98
+ theme: $.from('theme').def(''),
99
+ darkTheme: $.from('dark_theme').def(''),
100
+ mainMenu: $.from('sp_rectangle_menu').def(''),
101
+ categoryHomePage: $.from('sc_category_page').def(''),
102
+ homePage: $.from('homepage').def(''),
103
+ searchResultsConfiguration: $.from('search_results_configuration').def(''),
104
+ searchApplication: $.from('search_application').def(''),
105
+ alternatePortal: $.from('alternate_portal').def(''),
106
+ catalogHomePage: $.from('sc_catalog_page').def(''),
107
+ loginPage: $.from('login_page').def(''),
108
+ knowledgeHomePage: $.from('kb_knowledge_page').def(''),
109
+ chatQueue: $.from('sp_chat_queue').def(''),
110
+ notFoundPage: $.from('notfound_page').def(''),
111
+ textIndexGroup: $.from('ts_index_group').def(''),
112
+ enableAiSearch: $.from('enable_ais').toBoolean().def(false),
113
+ enableCertificateBasedAuthentication: $.from('enable_certificate_based_authentication')
114
+ .toBoolean()
115
+ .def(false),
116
+ defaultPortal: $.from('default').toBoolean().def(false),
117
+ enableWebEmbeddables: $.from('enable_embeddables').toBoolean().def(false),
118
+ enableFavorites: $.from('enable_favorites').toBoolean().def(false),
119
+ inactive: $.from('inactive').toBoolean().def(false),
120
+ hidePortalName: $.from('hide_portal_name').toBoolean().def(false),
121
+ supportRightToLeftLanguages: $.from('rtl_enabled').toBoolean().def(false),
122
+ searchSources: $.val(searchSources).def([]),
123
+ knowledgeBases: $.val(knowledgeBases).def([]),
124
+ catalogs: $.val(catalogs).def([]),
125
+ taxonomies: $.val(taxonomies).def([]),
126
+ })),
127
+ ],
128
+ })
129
+
130
+ return {
131
+ success: true,
132
+ value: portalRecord,
133
+ }
134
+ },
135
+ },
136
+ m2m_sp_portal_search_source: {
137
+ coalesce: ['sp_portal', 'sp_search_source'],
138
+ },
139
+ m2m_sp_portal_knowledge_base: {
140
+ coalesce: ['sp_portal', 'kb_knowledge_base'],
141
+ },
142
+ m2m_sp_portal_catalog: {
143
+ coalesce: ['sp_portal', 'sc_catalog'],
144
+ },
145
+ m2m_sp_portal_taxonomy: {
146
+ coalesce: ['sp_portal', 'taxonomy'],
147
+ },
148
+ },
149
+ shapes: [
150
+ {
151
+ shape: CallExpressionShape,
152
+ fileTypes: ['fluent'],
153
+ async toRecord(callExpression, { factory, diagnostics }) {
154
+ if (callExpression.getCallee() !== 'ServicePortal') {
155
+ return { success: false }
156
+ }
157
+ const portalArgs = callExpression.getArgument(0).asObject()
158
+
159
+ const urlSuffix = portalArgs.get('urlSuffix').ifString()
160
+ if (urlSuffix) {
161
+ const raw = urlSuffix.getValue()
162
+ let normalized = raw.toLowerCase().replace(/[^a-zA-Z0-9_]/g, '_')
163
+ while (normalized.indexOf('__') !== -1) {
164
+ normalized = normalized.replace(/__/g, '_')
165
+ }
166
+ while (normalized !== '' && normalized.charAt(normalized.length - 1) === '_') {
167
+ normalized = normalized.substring(0, normalized.length - 1)
168
+ }
169
+ if (raw !== normalized) {
170
+ diagnostics.error(
171
+ urlSuffix.getOriginalNode(),
172
+ `Invalid url_suffix '${raw}'. Use lowercase alphanumeric and single underscores only (e.g. '${normalized}')`
173
+ )
174
+ }
175
+ }
176
+ const catalogsForM2M = portalArgs.get('catalogs')?.ifArray()?.getElements() ?? []
177
+ const knowledgeBasesForM2M = portalArgs.get('knowledgeBases')?.ifArray()?.getElements() ?? []
178
+
179
+ const deprecatedKnowledgeBase = portalArgs.get('knowledgeBase')
180
+ if (deprecatedKnowledgeBase?.isDefined()) {
181
+ if (knowledgeBasesForM2M.length > 0) {
182
+ diagnostics.error(
183
+ deprecatedKnowledgeBase.getOriginalNode(),
184
+ `Cannot use both 'knowledgeBase' and 'knowledgeBases'. Remove 'knowledgeBase' and use only the 'knowledgeBases' array instead.`
185
+ )
186
+ } else {
187
+ diagnostics.warn(
188
+ deprecatedKnowledgeBase.getOriginalNode(),
189
+ `'knowledgeBase' is deprecated. Use the 'knowledgeBases' array instead.`
190
+ )
191
+ }
192
+ }
193
+
194
+ const deprecatedCatalog = portalArgs.get('catalog')
195
+ if (deprecatedCatalog?.isDefined()) {
196
+ if (catalogsForM2M.length > 0) {
197
+ diagnostics.error(
198
+ deprecatedCatalog.getOriginalNode(),
199
+ `Cannot use both 'catalog' and 'catalogs'. Remove 'catalog' and use only the 'catalogs' array instead.`
200
+ )
201
+ } else {
202
+ diagnostics.warn(
203
+ deprecatedCatalog.getOriginalNode(),
204
+ `'catalog' is deprecated. Use the 'catalogs' array instead.`
205
+ )
206
+ }
207
+ }
208
+
209
+ // Build portal properties
210
+ const baseProperties = portalArgs.transform(({ $ }) => ({
211
+ title: $,
212
+ url_suffix: $.from('urlSuffix').def(''),
213
+ icon: $.from('icon'),
214
+ logo: $.from('logo'),
215
+ logo_alt_text: $.from('logoAltText'),
216
+ quick_start_config: $.from('quickStartConfig'),
217
+ embeddable_macroponents: $.from('embeddableMacroponents'),
218
+ communication_channels: $.from('communicationChannels'),
219
+ css_variables: $.from('cssVariables'),
220
+ theme: $.from('theme'),
221
+ dark_theme: $.from('darkTheme'),
222
+ sp_rectangle_menu: $.from('mainMenu'),
223
+ sc_category_page: $.from('categoryHomePage'),
224
+ homepage: $.from('homePage'),
225
+ search_results_configuration: $.from('searchResultsConfiguration'),
226
+ search_application: $.from('searchApplication'),
227
+ alternate_portal: $.from('alternatePortal'),
228
+ sc_catalog_page: $.from('catalogHomePage'),
229
+ login_page: $.from('loginPage'),
230
+ kb_knowledge_page: $.from('knowledgeHomePage'),
231
+ sp_chat_queue: $.from('chatQueue'),
232
+ notfound_page: $.from('notFoundPage'),
233
+ ts_index_group: $.from('textIndexGroup'),
234
+ ...(knowledgeBasesForM2M.length === 0 ? { kb_knowledge_base: $.from('knowledgeBase') } : {}),
235
+ ...(catalogsForM2M.length === 0 ? { sc_catalog: $.from('catalog') } : {}),
236
+ enable_ais: $.from('enableAiSearch').def(false),
237
+ enable_certificate_based_authentication: $.from('enableCertificateBasedAuthentication').def(false),
238
+ default: $.from('defaultPortal').def(false),
239
+ enable_embeddables: $.from('enableWebEmbeddables').def(false),
240
+ enable_favorites: $.from('enableFavorites').def(false),
241
+ inactive: $.from('inactive').def(false),
242
+ hide_portal_name: $.from('hidePortalName').def(false),
243
+ rtl_enabled: $.from('supportRightToLeftLanguages').def(false),
244
+ }))
245
+
246
+ const portalRecord = await factory.createRecord({
247
+ source: callExpression,
248
+ table: 'sp_portal',
249
+ explicitId: portalArgs.get('$id'),
250
+ properties: baseProperties,
251
+ })
252
+
253
+ // Handle search sources
254
+ const searchSources = portalArgs.get('searchSources')?.ifArray()?.getElements() ?? []
255
+
256
+ const searchSourceRecords: Record[] = []
257
+ for (const source of searchSources) {
258
+ const sourceObj = source.asObject()
259
+ const searchSourceRecord = await factory.createRecord({
260
+ source: callExpression,
261
+ table: 'm2m_sp_portal_search_source',
262
+ properties: {
263
+ sp_portal: portalRecord,
264
+ sp_search_source: sourceObj.get('searchSource'),
265
+ order: convertToNumber(sourceObj.get('order'), 100),
266
+ },
267
+ })
268
+ searchSourceRecords.push(searchSourceRecord)
269
+ }
270
+
271
+ // Handle knowledge bases
272
+
273
+ const knowledgeBaseRecords: Record[] = []
274
+ for (const kb of knowledgeBasesForM2M) {
275
+ const kbObj = kb.asObject()
276
+ const knowledgeBaseRecord = await factory.createRecord({
277
+ source: callExpression,
278
+ table: 'm2m_sp_portal_knowledge_base',
279
+ properties: {
280
+ sp_portal: portalRecord,
281
+ kb_knowledge_base: kbObj.get('knowledgeBase'),
282
+ order: convertToNumber(kbObj.get('order'), 100),
283
+ active: kbObj.get('active')?.isUndefined()
284
+ ? true
285
+ : kbObj.get('active').toBoolean().getValue(),
286
+ },
287
+ })
288
+ knowledgeBaseRecords.push(knowledgeBaseRecord)
289
+ }
290
+
291
+ // Handle catalogs
292
+ const catalogRecords: Record[] = []
293
+ for (const cat of catalogsForM2M) {
294
+ const catObj = cat.asObject()
295
+ const catalogRecord = await factory.createRecord({
296
+ source: callExpression,
297
+ table: 'm2m_sp_portal_catalog',
298
+ properties: {
299
+ sp_portal: portalRecord,
300
+ sc_catalog: catObj.get('catalog'),
301
+ order: convertToNumber(catObj.get('order'), 100),
302
+ active: catObj.get('active')?.isUndefined()
303
+ ? true
304
+ : catObj.get('active').toBoolean().getValue(),
305
+ },
306
+ })
307
+ catalogRecords.push(catalogRecord)
308
+ }
309
+
310
+ // Handle taxonomies
311
+ const taxonomies = portalArgs.get('taxonomies')?.ifArray()?.getElements() ?? []
312
+ const taxonomyRecords: Record[] = []
313
+ for (const tax of taxonomies) {
314
+ const taxObj = tax.asObject()
315
+ const taxonomyRecord = await factory.createRecord({
316
+ source: callExpression,
317
+ table: 'm2m_sp_portal_taxonomy',
318
+ properties: {
319
+ sp_portal: portalRecord,
320
+ taxonomy: taxObj.get('taxonomy'),
321
+ order: convertToNumber(taxObj.get('order'), 100),
322
+ active: taxObj.get('active')?.isUndefined()
323
+ ? true
324
+ : taxObj.get('active').toBoolean().getValue(),
325
+ },
326
+ })
327
+ taxonomyRecords.push(taxonomyRecord)
328
+ }
329
+
330
+ return {
331
+ success: true,
332
+ value: portalRecord.with(
333
+ ...searchSourceRecords,
334
+ ...knowledgeBaseRecords,
335
+ ...catalogRecords,
336
+ ...taxonomyRecords
337
+ ),
338
+ }
339
+ },
340
+ },
341
+ ],
342
+ })
@@ -0,0 +1,135 @@
1
+ import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core'
2
+ import { NowIdShape } from '../now-id-plugin'
3
+ import { DEFAULT_ORDER, getIncludeRecords } from './utils'
4
+ import { createSdkDocEntry } from '../utils'
5
+
6
+ export const SPThemePlugin = Plugin.create({
7
+ name: 'SPThemePlugin',
8
+ docs: [createSdkDocEntry('SPTheme', ['sp_theme'])],
9
+ records: {
10
+ sp_theme: {
11
+ relationships: {
12
+ m2m_sp_theme_js_include: { via: 'sp_theme', descendant: true },
13
+ m2m_sp_theme_css_include: { via: 'sp_theme', descendant: true },
14
+ },
15
+ toShape(record, { descendants }) {
16
+ const cssIncludeRecords = descendants.query('m2m_sp_theme_css_include')
17
+ const cssIncludes = cssIncludeRecords
18
+ .map((m2m) => {
19
+ const orderValue = m2m.get('order')
20
+ const order =
21
+ (orderValue?.ifString()?.isEmpty() ? undefined : orderValue?.toNumber()?.getValue()) ??
22
+ DEFAULT_ORDER
23
+ return {
24
+ order,
25
+ include: m2m.get('sp_css_include'),
26
+ }
27
+ })
28
+ .sort((a, b) => a.order - b.order)
29
+
30
+ const jsIncludeRecords = descendants.query('m2m_sp_theme_js_include')
31
+ const jsIncludes = jsIncludeRecords
32
+ .map((m2m) => {
33
+ const orderValue = m2m.get('order')
34
+ const order =
35
+ (orderValue?.ifString()?.isEmpty() ? undefined : orderValue?.toNumber()?.getValue()) ??
36
+ DEFAULT_ORDER
37
+ return {
38
+ order,
39
+ include: m2m.get('sp_js_include'),
40
+ }
41
+ })
42
+ .sort((a, b) => a.order - b.order)
43
+
44
+ const themeOptions = record.transform(({ $ }) => ({
45
+ $id: $.val(NowIdShape.from(record)),
46
+ name: $,
47
+ customCss: $.from('css_variables').def(''),
48
+ header: $.def(''),
49
+ footer: $.def(''),
50
+ fixedHeader: $.from('navbar_fixed').toBoolean().def(true),
51
+ fixedFooter: $.from('footer_fixed').toBoolean().def(true),
52
+ turnOffScssCompilation: $.from('turn_off_scss_compilation').toBoolean().def(false),
53
+ matchingNextExperienceTheme: $.from('matching_now_experience_theme').def(''),
54
+ cssIncludes: $.val(cssIncludes.length > 0 ? cssIncludes : undefined),
55
+ jsIncludes: $.val(jsIncludes.length > 0 ? jsIncludes : undefined),
56
+ icon: $.def(''),
57
+ logo: $.def(''),
58
+ logoAltText: $.from('logo_alt_text').def(''),
59
+ }))
60
+
61
+ return {
62
+ success: true,
63
+ value: new CallExpressionShape({
64
+ source: record,
65
+ callee: 'SPTheme',
66
+ args: [themeOptions],
67
+ }),
68
+ }
69
+ },
70
+ },
71
+ m2m_sp_theme_css_include: {
72
+ coalesce: ['sp_css_include', 'sp_theme'],
73
+ },
74
+ m2m_sp_theme_js_include: {
75
+ coalesce: ['sp_js_include', 'sp_theme'],
76
+ },
77
+ },
78
+ shapes: [
79
+ {
80
+ shape: CallExpressionShape,
81
+ fileTypes: ['fluent'],
82
+ async toRecord(callExpression, { diagnostics, factory }) {
83
+ if (callExpression.getCallee() !== 'SPTheme') {
84
+ return { success: false }
85
+ }
86
+
87
+ const theme = callExpression.getArgument(0).asObject()
88
+
89
+ const themeRecord = await factory.createRecord({
90
+ source: callExpression,
91
+ table: 'sp_theme',
92
+ explicitId: theme.get('$id'),
93
+ properties: theme.transform(({ $ }) => ({
94
+ name: $,
95
+ css_variables: $.from('customCss').def(''),
96
+ header: $,
97
+ footer: $,
98
+ navbar_fixed: $.from('fixedHeader').def(true),
99
+ footer_fixed: $.from('fixedFooter').def(true),
100
+ turn_off_scss_compilation: $.from('turnOffScssCompilation').def(false),
101
+ matching_now_experience_theme: $.from('matchingNextExperienceTheme').def(''),
102
+ icon: $,
103
+ logo: $,
104
+ logo_alt_text: $.from('logoAltText').def(''),
105
+ })),
106
+ })
107
+
108
+ const cssIncludes = await getIncludeRecords(
109
+ theme.get('cssIncludes'),
110
+ themeRecord.getId(),
111
+ factory,
112
+ 'm2m_sp_theme_css_include',
113
+ 'sp_css_include',
114
+ 'sp_theme',
115
+ diagnostics
116
+ )
117
+
118
+ const jsIncludes = await getIncludeRecords(
119
+ theme.get('jsIncludes'),
120
+ themeRecord.getId(),
121
+ factory,
122
+ 'm2m_sp_theme_js_include',
123
+ 'sp_js_include',
124
+ 'sp_theme',
125
+ diagnostics
126
+ )
127
+
128
+ return {
129
+ success: true,
130
+ value: themeRecord.with(...cssIncludes, ...jsIncludes),
131
+ }
132
+ },
133
+ },
134
+ ],
135
+ })