@servicenow/sdk-build-plugins 3.0.3 → 4.0.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 (359) hide show
  1. package/dist/acl-plugin.d.ts +19 -0
  2. package/dist/acl-plugin.js +210 -0
  3. package/dist/acl-plugin.js.map +1 -0
  4. package/dist/application-menu-plugin.d.ts +18 -0
  5. package/dist/application-menu-plugin.js +104 -0
  6. package/dist/application-menu-plugin.js.map +1 -0
  7. package/dist/arrow-function-plugin.d.ts +16 -0
  8. package/dist/arrow-function-plugin.js +107 -0
  9. package/dist/arrow-function-plugin.js.map +1 -0
  10. package/dist/atf/step-configs.d.ts +37 -0
  11. package/dist/atf/step-configs.js +2236 -0
  12. package/dist/atf/step-configs.js.map +1 -0
  13. package/dist/atf/test-plugin.d.ts +4 -0
  14. package/dist/atf/test-plugin.js +591 -0
  15. package/dist/atf/test-plugin.js.map +1 -0
  16. package/dist/basic-syntax-plugin.d.ts +2 -0
  17. package/dist/basic-syntax-plugin.js +636 -0
  18. package/dist/basic-syntax-plugin.js.map +1 -0
  19. package/dist/business-rule-plugin.d.ts +3 -0
  20. package/dist/business-rule-plugin.js +205 -0
  21. package/dist/business-rule-plugin.js.map +1 -0
  22. package/dist/call-expression-plugin.d.ts +2 -0
  23. package/dist/call-expression-plugin.js +175 -0
  24. package/dist/call-expression-plugin.js.map +1 -0
  25. package/dist/client-script-plugin.d.ts +29 -0
  26. package/dist/client-script-plugin.js +157 -0
  27. package/dist/client-script-plugin.js.map +1 -0
  28. package/dist/column/column-helper.d.ts +12 -0
  29. package/dist/column/column-helper.js +84 -0
  30. package/dist/column/column-helper.js.map +1 -0
  31. package/dist/column/column-to-record.d.ts +3 -0
  32. package/dist/column/column-to-record.js +105 -0
  33. package/dist/column/column-to-record.js.map +1 -0
  34. package/dist/column-plugin.d.ts +8 -0
  35. package/dist/column-plugin.js +453 -0
  36. package/dist/column-plugin.js.map +1 -0
  37. package/dist/cross-scope-privilege-plugin.d.ts +15 -0
  38. package/dist/cross-scope-privilege-plugin.js +82 -0
  39. package/dist/cross-scope-privilege-plugin.js.map +1 -0
  40. package/dist/html-import-plugin.d.ts +2 -0
  41. package/dist/html-import-plugin.js +72 -0
  42. package/dist/html-import-plugin.js.map +1 -0
  43. package/dist/index.d.ts +37 -21
  44. package/dist/index.js +40 -45
  45. package/dist/index.js.map +1 -1
  46. package/dist/json-plugin.d.ts +15 -0
  47. package/dist/json-plugin.js +104 -0
  48. package/dist/json-plugin.js.map +1 -0
  49. package/dist/list-plugin.d.ts +2 -0
  50. package/dist/list-plugin.js +191 -0
  51. package/dist/list-plugin.js.map +1 -0
  52. package/dist/now-config-plugin.d.ts +4 -0
  53. package/dist/now-config-plugin.js +154 -0
  54. package/dist/now-config-plugin.js.map +1 -0
  55. package/dist/now-id-plugin.d.ts +11 -0
  56. package/dist/now-id-plugin.js +71 -0
  57. package/dist/now-id-plugin.js.map +1 -0
  58. package/dist/now-include-plugin.d.ts +16 -0
  59. package/dist/now-include-plugin.js +118 -0
  60. package/dist/now-include-plugin.js.map +1 -0
  61. package/dist/now-ref-plugin.d.ts +2 -0
  62. package/dist/now-ref-plugin.js +43 -0
  63. package/dist/now-ref-plugin.js.map +1 -0
  64. package/dist/now-unresolved-plugin.d.ts +2 -0
  65. package/dist/now-unresolved-plugin.js +32 -0
  66. package/dist/now-unresolved-plugin.js.map +1 -0
  67. package/dist/package-json-plugin.d.ts +2 -0
  68. package/dist/package-json-plugin.js +70 -0
  69. package/dist/package-json-plugin.js.map +1 -0
  70. package/dist/property-plugin.d.ts +2 -0
  71. package/dist/property-plugin.js +105 -0
  72. package/dist/property-plugin.js.map +1 -0
  73. package/dist/record-plugin.d.ts +43 -0
  74. package/dist/record-plugin.js +147 -0
  75. package/dist/record-plugin.js.map +1 -0
  76. package/dist/repack/index.d.ts +1 -0
  77. package/dist/repack/index.js +10 -2
  78. package/dist/repack/index.js.map +1 -1
  79. package/dist/repack/lint/Rules.d.ts +1 -1
  80. package/dist/repack/lint/Rules.js +7 -3
  81. package/dist/repack/lint/Rules.js.map +1 -1
  82. package/dist/repack/lint/index.js +1 -1
  83. package/dist/rest-api-plugin.d.ts +2 -0
  84. package/dist/rest-api-plugin.js +469 -0
  85. package/dist/rest-api-plugin.js.map +1 -0
  86. package/dist/role-plugin.d.ts +2 -0
  87. package/dist/role-plugin.js +117 -0
  88. package/dist/role-plugin.js.map +1 -0
  89. package/dist/script-action-plugin.d.ts +2 -0
  90. package/dist/script-action-plugin.js +62 -0
  91. package/dist/script-action-plugin.js.map +1 -0
  92. package/dist/script-include-plugin.d.ts +2 -0
  93. package/dist/script-include-plugin.js +102 -0
  94. package/dist/script-include-plugin.js.map +1 -0
  95. package/dist/server-module-plugin/index.d.ts +14 -0
  96. package/dist/server-module-plugin/index.js +378 -0
  97. package/dist/server-module-plugin/index.js.map +1 -0
  98. package/dist/server-module-plugin/sbom-builder.d.ts +45 -0
  99. package/dist/server-module-plugin/sbom-builder.js +179 -0
  100. package/dist/server-module-plugin/sbom-builder.js.map +1 -0
  101. package/dist/service-portal/angular-provider-plugin.d.ts +2 -0
  102. package/dist/service-portal/angular-provider-plugin.js +78 -0
  103. package/dist/service-portal/angular-provider-plugin.js.map +1 -0
  104. package/dist/service-portal/dependency-plugin.d.ts +2 -0
  105. package/dist/service-portal/dependency-plugin.js +235 -0
  106. package/dist/service-portal/dependency-plugin.js.map +1 -0
  107. package/dist/service-portal/widget-plugin.d.ts +6 -0
  108. package/dist/service-portal/widget-plugin.js +230 -0
  109. package/dist/service-portal/widget-plugin.js.map +1 -0
  110. package/dist/static-content-plugin.d.ts +2 -0
  111. package/dist/static-content-plugin.js +272 -0
  112. package/dist/static-content-plugin.js.map +1 -0
  113. package/dist/table-plugin.d.ts +3 -0
  114. package/dist/table-plugin.js +1324 -0
  115. package/dist/table-plugin.js.map +1 -0
  116. package/dist/ui-action-plugin.d.ts +2 -0
  117. package/dist/ui-action-plugin.js +291 -0
  118. package/dist/ui-action-plugin.js.map +1 -0
  119. package/dist/ui-page-plugin.d.ts +2 -0
  120. package/dist/ui-page-plugin.js +165 -0
  121. package/dist/ui-page-plugin.js.map +1 -0
  122. package/dist/user-preference-plugin.d.ts +15 -0
  123. package/dist/user-preference-plugin.js +63 -0
  124. package/dist/user-preference-plugin.js.map +1 -0
  125. package/dist/utils.d.ts +17 -0
  126. package/dist/utils.js +72 -0
  127. package/dist/utils.js.map +1 -0
  128. package/dist/view-plugin.d.ts +2 -0
  129. package/dist/view-plugin.js +45 -0
  130. package/dist/view-plugin.js.map +1 -0
  131. package/package.json +17 -13
  132. package/src/acl-plugin.ts +256 -0
  133. package/src/application-menu-plugin.ts +109 -0
  134. package/src/arrow-function-plugin.ts +127 -0
  135. package/src/atf/step-configs.ts +2284 -0
  136. package/src/atf/test-plugin.ts +728 -0
  137. package/src/basic-syntax-plugin.ts +729 -0
  138. package/src/business-rule-plugin.ts +266 -0
  139. package/src/call-expression-plugin.ts +202 -0
  140. package/src/client-script-plugin.ts +170 -0
  141. package/src/column/column-helper.ts +119 -0
  142. package/src/column/column-to-record.ts +131 -0
  143. package/src/column-plugin.ts +506 -0
  144. package/src/cross-scope-privilege-plugin.ts +82 -0
  145. package/src/html-import-plugin.ts +79 -0
  146. package/src/index.ts +39 -21
  147. package/src/json-plugin.ts +128 -0
  148. package/src/list-plugin.ts +222 -0
  149. package/src/now-config-plugin.ts +194 -0
  150. package/src/now-id-plugin.ts +78 -0
  151. package/src/now-include-plugin.ts +140 -0
  152. package/src/now-ref-plugin.ts +48 -0
  153. package/src/now-unresolved-plugin.ts +30 -0
  154. package/src/package-json-plugin.ts +87 -0
  155. package/src/property-plugin.ts +118 -0
  156. package/src/record-plugin.ts +171 -0
  157. package/src/repack/index.ts +10 -1
  158. package/src/repack/lint/Rules.ts +5 -4
  159. package/src/repack/lint/index.ts +1 -1
  160. package/src/rest-api-plugin.ts +651 -0
  161. package/src/role-plugin.ts +128 -0
  162. package/src/script-action-plugin.ts +63 -0
  163. package/src/script-include-plugin.ts +110 -0
  164. package/src/server-module-plugin/index.ts +470 -0
  165. package/src/server-module-plugin/sbom-builder.ts +183 -0
  166. package/src/service-portal/angular-provider-plugin.ts +83 -0
  167. package/src/service-portal/dependency-plugin.ts +284 -0
  168. package/src/service-portal/widget-plugin.ts +263 -0
  169. package/src/static-content-plugin.ts +254 -0
  170. package/src/table-plugin.ts +1698 -0
  171. package/src/ui-action-plugin.ts +324 -0
  172. package/src/ui-page-plugin.ts +168 -0
  173. package/src/user-preference-plugin.ts +62 -0
  174. package/src/utils.ts +69 -0
  175. package/src/view-plugin.ts +46 -0
  176. package/dist/AttachmentPlugin.d.ts +0 -254
  177. package/dist/AttachmentPlugin.js +0 -220
  178. package/dist/AttachmentPlugin.js.map +0 -1
  179. package/dist/BusinessRulePlugin.d.ts +0 -30
  180. package/dist/BusinessRulePlugin.js +0 -149
  181. package/dist/BusinessRulePlugin.js.map +0 -1
  182. package/dist/CrossScopePrivilegePlugin.d.ts +0 -35
  183. package/dist/CrossScopePrivilegePlugin.js +0 -80
  184. package/dist/CrossScopePrivilegePlugin.js.map +0 -1
  185. package/dist/DefaultPlugin.d.ts +0 -86
  186. package/dist/DefaultPlugin.js +0 -226
  187. package/dist/DefaultPlugin.js.map +0 -1
  188. package/dist/HtmlTemplatePlugin.d.ts +0 -21
  189. package/dist/HtmlTemplatePlugin.js +0 -29
  190. package/dist/HtmlTemplatePlugin.js.map +0 -1
  191. package/dist/IdPlugin.d.ts +0 -28
  192. package/dist/IdPlugin.js +0 -68
  193. package/dist/IdPlugin.js.map +0 -1
  194. package/dist/IncludePlugin.d.ts +0 -34
  195. package/dist/IncludePlugin.js +0 -155
  196. package/dist/IncludePlugin.js.map +0 -1
  197. package/dist/JsonPlugin.d.ts +0 -28
  198. package/dist/JsonPlugin.js +0 -69
  199. package/dist/JsonPlugin.js.map +0 -1
  200. package/dist/ListPlugin.d.ts +0 -93
  201. package/dist/ListPlugin.js +0 -456
  202. package/dist/ListPlugin.js.map +0 -1
  203. package/dist/NowConfigPlugin.d.ts +0 -45
  204. package/dist/NowConfigPlugin.js +0 -64
  205. package/dist/NowConfigPlugin.js.map +0 -1
  206. package/dist/PackageJsonPlugin.d.ts +0 -34
  207. package/dist/PackageJsonPlugin.js +0 -63
  208. package/dist/PackageJsonPlugin.js.map +0 -1
  209. package/dist/PropertyPlugin.d.ts +0 -51
  210. package/dist/PropertyPlugin.js +0 -181
  211. package/dist/PropertyPlugin.js.map +0 -1
  212. package/dist/ScriptTemplatePlugin.d.ts +0 -13
  213. package/dist/ScriptTemplatePlugin.js +0 -55
  214. package/dist/ScriptTemplatePlugin.js.map +0 -1
  215. package/dist/ServerModulePlugin.d.ts +0 -75
  216. package/dist/ServerModulePlugin.js +0 -368
  217. package/dist/ServerModulePlugin.js.map +0 -1
  218. package/dist/UserPreferencePlugin.d.ts +0 -19
  219. package/dist/UserPreferencePlugin.js +0 -32
  220. package/dist/UserPreferencePlugin.js.map +0 -1
  221. package/dist/aclAndRole/AclPlugin.d.ts +0 -82
  222. package/dist/aclAndRole/AclPlugin.js +0 -262
  223. package/dist/aclAndRole/AclPlugin.js.map +0 -1
  224. package/dist/aclAndRole/RolePlugin.d.ts +0 -66
  225. package/dist/aclAndRole/RolePlugin.js +0 -179
  226. package/dist/aclAndRole/RolePlugin.js.map +0 -1
  227. package/dist/aclAndRole/Util.d.ts +0 -3
  228. package/dist/aclAndRole/Util.js +0 -90
  229. package/dist/aclAndRole/Util.js.map +0 -1
  230. package/dist/app/ApplicationMenuPlugin.d.ts +0 -34
  231. package/dist/app/ApplicationMenuPlugin.js +0 -112
  232. package/dist/app/ApplicationMenuPlugin.js.map +0 -1
  233. package/dist/db/ColumnPlugins.d.ts +0 -750
  234. package/dist/db/ColumnPlugins.js +0 -114
  235. package/dist/db/ColumnPlugins.js.map +0 -1
  236. package/dist/db/DBUtils.d.ts +0 -2
  237. package/dist/db/DBUtils.js +0 -27
  238. package/dist/db/DBUtils.js.map +0 -1
  239. package/dist/db/DocumentationPlugin.d.ts +0 -67
  240. package/dist/db/DocumentationPlugin.js +0 -258
  241. package/dist/db/DocumentationPlugin.js.map +0 -1
  242. package/dist/db/LicensingPlugin.d.ts +0 -60
  243. package/dist/db/LicensingPlugin.js +0 -117
  244. package/dist/db/LicensingPlugin.js.map +0 -1
  245. package/dist/db/RecordPlugin.d.ts +0 -133
  246. package/dist/db/RecordPlugin.js +0 -337
  247. package/dist/db/RecordPlugin.js.map +0 -1
  248. package/dist/db/TablePlugin.d.ts +0 -231
  249. package/dist/db/TablePlugin.js +0 -1630
  250. package/dist/db/TablePlugin.js.map +0 -1
  251. package/dist/db/index.d.ts +0 -6
  252. package/dist/db/index.js +0 -32
  253. package/dist/db/index.js.map +0 -1
  254. package/dist/scriptedRESTAPI/RESTDeserializationUtils.d.ts +0 -10
  255. package/dist/scriptedRESTAPI/RESTDeserializationUtils.js +0 -373
  256. package/dist/scriptedRESTAPI/RESTDeserializationUtils.js.map +0 -1
  257. package/dist/scriptedRESTAPI/RESTSerializationUtils.d.ts +0 -13
  258. package/dist/scriptedRESTAPI/RESTSerializationUtils.js +0 -177
  259. package/dist/scriptedRESTAPI/RESTSerializationUtils.js.map +0 -1
  260. package/dist/scriptedRESTAPI/RestApiPlugin.d.ts +0 -81
  261. package/dist/scriptedRESTAPI/RestApiPlugin.js +0 -345
  262. package/dist/scriptedRESTAPI/RestApiPlugin.js.map +0 -1
  263. package/dist/scriptedRESTAPI/RestSchemaUtils.d.ts +0 -190
  264. package/dist/scriptedRESTAPI/RestSchemaUtils.js +0 -53
  265. package/dist/scriptedRESTAPI/RestSchemaUtils.js.map +0 -1
  266. package/dist/scriptedRESTAPI/RestUtils.d.ts +0 -69
  267. package/dist/scriptedRESTAPI/RestUtils.js +0 -497
  268. package/dist/scriptedRESTAPI/RestUtils.js.map +0 -1
  269. package/dist/scripts/ClientScriptPlugin.d.ts +0 -64
  270. package/dist/scripts/ClientScriptPlugin.js +0 -170
  271. package/dist/scripts/ClientScriptPlugin.js.map +0 -1
  272. package/dist/scripts/scriptUtils.d.ts +0 -1
  273. package/dist/scripts/scriptUtils.js +0 -9
  274. package/dist/scripts/scriptUtils.js.map +0 -1
  275. package/dist/uxf/ExperiencePlugin.d.ts +0 -45
  276. package/dist/uxf/ExperiencePlugin.js +0 -61
  277. package/dist/uxf/ExperiencePlugin.js.map +0 -1
  278. package/dist/uxf/RoutesPlugin.d.ts +0 -29
  279. package/dist/uxf/RoutesPlugin.js +0 -181
  280. package/dist/uxf/RoutesPlugin.js.map +0 -1
  281. package/dist/uxf/UxfFormulaParser/cleanUxValue.d.ts +0 -4
  282. package/dist/uxf/UxfFormulaParser/cleanUxValue.js +0 -65
  283. package/dist/uxf/UxfFormulaParser/cleanUxValue.js.map +0 -1
  284. package/dist/uxf/UxfFormulaParser/grammerParser/api.d.ts +0 -189
  285. package/dist/uxf/UxfFormulaParser/grammerParser/api.js +0 -158
  286. package/dist/uxf/UxfFormulaParser/grammerParser/api.js.map +0 -1
  287. package/dist/uxf/UxfFormulaParser/grammerParser/clientTransformMap.d.ts +0 -13
  288. package/dist/uxf/UxfFormulaParser/grammerParser/clientTransformMap.js +0 -604
  289. package/dist/uxf/UxfFormulaParser/grammerParser/clientTransformMap.js.map +0 -1
  290. package/dist/uxf/UxfFormulaParser/grammerParser/grammarParser.d.ts +0 -12
  291. package/dist/uxf/UxfFormulaParser/grammerParser/grammarParser.js +0 -551
  292. package/dist/uxf/UxfFormulaParser/grammerParser/grammarParser.js.map +0 -1
  293. package/dist/uxf/UxfFormulaParser/grammerParser/spanHelpers.d.ts +0 -31
  294. package/dist/uxf/UxfFormulaParser/grammerParser/spanHelpers.js +0 -64
  295. package/dist/uxf/UxfFormulaParser/grammerParser/spanHelpers.js.map +0 -1
  296. package/dist/uxf/UxfFormulaParser/index.d.ts +0 -3
  297. package/dist/uxf/UxfFormulaParser/index.js +0 -11
  298. package/dist/uxf/UxfFormulaParser/index.js.map +0 -1
  299. package/dist/uxf/UxfFormulaParser/parser.d.ts +0 -8
  300. package/dist/uxf/UxfFormulaParser/parser.js +0 -87
  301. package/dist/uxf/UxfFormulaParser/parser.js.map +0 -1
  302. package/dist/uxf/UxfFormulaParser/utils/getErrorMsg.d.ts +0 -8
  303. package/dist/uxf/UxfFormulaParser/utils/getErrorMsg.js +0 -17
  304. package/dist/uxf/UxfFormulaParser/utils/getErrorMsg.js.map +0 -1
  305. package/dist/uxf/constants.d.ts +0 -2
  306. package/dist/uxf/constants.js +0 -8
  307. package/dist/uxf/constants.js.map +0 -1
  308. package/dist/uxf/index.d.ts +0 -2
  309. package/dist/uxf/index.js +0 -11
  310. package/dist/uxf/index.js.map +0 -1
  311. package/dist/uxf/tectonicIdGenerator.d.ts +0 -12
  312. package/dist/uxf/tectonicIdGenerator.js +0 -79
  313. package/dist/uxf/tectonicIdGenerator.js.map +0 -1
  314. package/src/AttachmentPlugin.ts +0 -268
  315. package/src/BusinessRulePlugin.ts +0 -238
  316. package/src/CrossScopePrivilegePlugin.ts +0 -115
  317. package/src/DefaultPlugin.ts +0 -288
  318. package/src/HtmlTemplatePlugin.ts +0 -31
  319. package/src/IdPlugin.ts +0 -74
  320. package/src/IncludePlugin.ts +0 -206
  321. package/src/JsonPlugin.ts +0 -76
  322. package/src/ListPlugin.ts +0 -570
  323. package/src/NowConfigPlugin.ts +0 -69
  324. package/src/PackageJsonPlugin.ts +0 -68
  325. package/src/PropertyPlugin.ts +0 -237
  326. package/src/ScriptTemplatePlugin.ts +0 -53
  327. package/src/ServerModulePlugin.ts +0 -480
  328. package/src/UserPreferencePlugin.ts +0 -45
  329. package/src/aclAndRole/AclPlugin.ts +0 -420
  330. package/src/aclAndRole/RolePlugin.ts +0 -254
  331. package/src/aclAndRole/Util.ts +0 -113
  332. package/src/app/ApplicationMenuPlugin.ts +0 -165
  333. package/src/db/ColumnPlugins.ts +0 -114
  334. package/src/db/DBUtils.ts +0 -36
  335. package/src/db/DocumentationPlugin.ts +0 -316
  336. package/src/db/LicensingPlugin.ts +0 -138
  337. package/src/db/RecordPlugin.ts +0 -459
  338. package/src/db/TablePlugin.ts +0 -2072
  339. package/src/db/index.ts +0 -6
  340. package/src/scriptedRESTAPI/RESTDeserializationUtils.ts +0 -419
  341. package/src/scriptedRESTAPI/RESTSerializationUtils.ts +0 -228
  342. package/src/scriptedRESTAPI/RestApiPlugin.ts +0 -469
  343. package/src/scriptedRESTAPI/RestSchemaUtils.ts +0 -72
  344. package/src/scriptedRESTAPI/RestUtils.ts +0 -569
  345. package/src/scripts/ClientScriptPlugin.ts +0 -257
  346. package/src/scripts/scriptUtils.ts +0 -5
  347. package/src/uxf/ExperiencePlugin.ts +0 -67
  348. package/src/uxf/RoutesPlugin.ts +0 -211
  349. package/src/uxf/UxfFormulaParser/cleanUxValue.ts +0 -73
  350. package/src/uxf/UxfFormulaParser/grammerParser/api.js +0 -166
  351. package/src/uxf/UxfFormulaParser/grammerParser/clientTransformMap.js +0 -606
  352. package/src/uxf/UxfFormulaParser/grammerParser/grammarParser.js +0 -551
  353. package/src/uxf/UxfFormulaParser/grammerParser/spanHelpers.js +0 -65
  354. package/src/uxf/UxfFormulaParser/index.ts +0 -4
  355. package/src/uxf/UxfFormulaParser/parser.ts +0 -64
  356. package/src/uxf/UxfFormulaParser/utils/getErrorMsg.ts +0 -13
  357. package/src/uxf/constants.ts +0 -4
  358. package/src/uxf/index.ts +0 -2
  359. package/src/uxf/tectonicIdGenerator.ts +0 -78
@@ -0,0 +1,324 @@
1
+ import { CallExpressionShape, Plugin, type RecordId, type Shape, type StringShape } from '@servicenow/sdk-build-core'
2
+ import { NowIdShape } from './now-id-plugin'
3
+ import { ModuleFunctionShape } from './server-module-plugin'
4
+
5
+ export const UiActionPlugin = Plugin.create({
6
+ name: 'UiActionPlugin',
7
+ records: {
8
+ sys_ui_action: {
9
+ relationships: {
10
+ sys_ui_action_role: {
11
+ via: 'sys_ui_action',
12
+ descendant: true,
13
+ relationships: {
14
+ sys_user_role: {
15
+ via: 'sys_user_role',
16
+ inverse: true,
17
+ },
18
+ },
19
+ },
20
+ sys_ui_action_view: {
21
+ via: 'sys_ui_action',
22
+ descendant: true,
23
+ relationships: {
24
+ sys_ui_view: {
25
+ via: 'sys_ui_view',
26
+ inverse: true,
27
+ },
28
+ },
29
+ },
30
+ },
31
+ toShape(record, { descendants }) {
32
+ const actionViews = descendants.query('sys_ui_action_view')
33
+ const excludeFrom: (RecordId | string)[] = [],
34
+ includeIn: (RecordId | string)[] = []
35
+ for (const actionView of actionViews) {
36
+ const viewName = actionView.getId().getKey('sys_ui_view')
37
+ if (!viewName) {
38
+ continue
39
+ }
40
+ const visibility = actionView.get('visibility').ifString()?.getValue()
41
+ visibility === 'exclude' ? excludeFrom.push(viewName) : includeIn.push(viewName)
42
+ }
43
+ const roles = descendants.query('sys_ui_action_role').map((m2m) => m2m.get('sys_user_role'))
44
+ const getBoolean = (key: string): boolean | undefined => {
45
+ return record.get(key)?.ifDefined()?.toBoolean().getValue()
46
+ }
47
+
48
+ const getString = (key: string): string | undefined => {
49
+ return record.get(key)?.ifString()?.getValue()
50
+ }
51
+
52
+ const form = {
53
+ showButton: getBoolean('form_button'),
54
+ showLink: getBoolean('form_link'),
55
+ showContextMenu: getBoolean('form_context_menu'),
56
+ style: getString('form_style'),
57
+ }
58
+
59
+ const list = {
60
+ showButton: getBoolean('list_button'),
61
+ showLink: getBoolean('list_link'),
62
+ showContextMenu: getBoolean('list_context_menu'),
63
+ style: getString('list_style'),
64
+ showListChoice: getBoolean('list_choice'),
65
+ showBannerButton: getBoolean('list_banner_button'),
66
+ showSaveWithFormButton: getBoolean('list_save_with_form_button'),
67
+ }
68
+
69
+ const client = {
70
+ isClient: getBoolean('client'),
71
+ isUi11Compatible: getBoolean('ui11_compatible'),
72
+ onClick: getString('onclick'),
73
+ isUi16Compatible: getBoolean('ui16_compatible'),
74
+ }
75
+
76
+ const workspace = {
77
+ clientScriptV2: getString('client_script_v2'),
78
+ showFormButtonV2: getBoolean('form_button_v2'),
79
+ showFormMenuButtonV2: getBoolean('form_menu_button_v2'),
80
+ isConfigurableWorkspace: getBoolean('format_for_configurable_workspace'),
81
+ }
82
+
83
+ // Extract messages from the record if available
84
+ const messages: string[] = []
85
+ const messagesField = record.get('messages')
86
+ if (messagesField?.isArray()) {
87
+ const messageValues = messagesField.asArray().getValue()
88
+ if (Array.isArray(messageValues)) {
89
+ messageValues.forEach((msg) => {
90
+ if (typeof msg === 'string') {
91
+ messages.push(msg)
92
+ }
93
+ })
94
+ }
95
+ } else if (messagesField?.ifString()) {
96
+ // Handle messages as a string (from XML)
97
+ const messageString = messagesField.ifString()?.getValue()
98
+ if (messageString) {
99
+ // Split by newlines and add each line as a separate message
100
+ const messageLines = messageString.split('\n')
101
+ messageLines.forEach((line) => {
102
+ if (line.trim()) {
103
+ messages.push(line)
104
+ }
105
+ })
106
+ }
107
+ }
108
+ return {
109
+ success: true,
110
+ value: new CallExpressionShape({
111
+ source: record,
112
+ callee: 'UiAction',
113
+ args: [
114
+ record.transform(({ $ }) => ({
115
+ $id: $.val(NowIdShape.from(record)),
116
+ table: $,
117
+ name: $,
118
+ active: $.toBoolean().def(true),
119
+ actionName: $.from('action_name').def(''),
120
+ form: $.val(form).def({
121
+ showButton: false,
122
+ showLink: false,
123
+ showContextMenu: false,
124
+ style: '',
125
+ }),
126
+ list: $.val(list).def({
127
+ showButton: false,
128
+ showLink: false,
129
+ showContextMenu: false,
130
+ style: '',
131
+ showListChoice: false,
132
+ showBannerButton: false,
133
+ showSaveWithFormButton: false,
134
+ }),
135
+ client: $.val(client).def({
136
+ isClient: false,
137
+ isUi11Compatible: false,
138
+ onClick: '',
139
+ isUi16Compatible: false,
140
+ }),
141
+ workspace: $.val(workspace).def({
142
+ clientScriptV2: '',
143
+ showFormButtonV2: false,
144
+ showFormMenuButtonV2: false,
145
+ isConfigurableWorkspace: false,
146
+ }),
147
+ comments: $.def(''),
148
+ messages: $.val(messages.length > 0 ? messages : []),
149
+ condition: $.def(''),
150
+ script: $.def(''),
151
+ hint: $.def(''),
152
+ order: $.map((o) => (o.ifString()?.getValue() === '' ? 100 : o))
153
+ .toNumber()
154
+ .def(100),
155
+ overrides: $.def(''),
156
+ showQuery: $.from('show_query').toBoolean().def(false),
157
+ showUpdate: $.from('show_update').toBoolean(),
158
+ showInsert: $.from('show_insert').toBoolean(),
159
+ showMultipleUpdate: $.from('show_multiple_update').toBoolean().def(false),
160
+ isolateScript: $.from('isolate_script').toBoolean().def(false),
161
+ roles: $.val(roles).def([]),
162
+ includeInViews: $.val(includeIn).def([]),
163
+ excludeFromViews: $.val(excludeFrom).def([]),
164
+ })),
165
+ ],
166
+ }),
167
+ }
168
+ },
169
+ },
170
+ sys_ui_action_role: {
171
+ coalesce: ['sys_ui_action', 'sys_user_role'],
172
+ },
173
+ sys_ui_action_view: {
174
+ coalesce: ['sys_ui_action', 'sys_ui_view'],
175
+ },
176
+ },
177
+ shapes: [
178
+ {
179
+ shape: CallExpressionShape,
180
+ fileTypes: ['fluent'],
181
+ async toRecord(callExpression, { diagnostics, factory }) {
182
+ if (callExpression.getCallee() !== 'UiAction') {
183
+ return { success: false }
184
+ }
185
+
186
+ const arg = callExpression.getArgument(0).asObject()
187
+ const isClient = arg.get(['client', 'isClient'])
188
+
189
+ const uiAction = factory.createRecord({
190
+ source: callExpression,
191
+ table: 'sys_ui_action',
192
+ explicitId: arg.get('$id'),
193
+ properties: arg.transform(({ $ }) => ({
194
+ name: $,
195
+ table: $,
196
+ action_name: $.from('actionName'),
197
+ comments: $.def(''),
198
+ active: $.def(true),
199
+ client: $.val(isClient),
200
+ onClick: $.val(arg.get(['client', 'onClick'])),
201
+ messages: $.val(
202
+ arg.get('messages')?.isArray()
203
+ ? arg.get('messages').asArray().getValue().join('\n')
204
+ : arg.get('messages')
205
+ ).def([]),
206
+ list_style: $.val(arg.get(['list', 'style'])),
207
+ form_style: $.val(arg.get(['form', 'style'])),
208
+ condition: $.def(''),
209
+ script: $.map(
210
+ (v) => v.if(ModuleFunctionShape)?.toString((n) => `${n}({{PARAMS}})`, ['current']) ?? v
211
+ )
212
+ .def('')
213
+ .toCdata(),
214
+ hint: $.def(''),
215
+ order: $.toNumber().def(100),
216
+ overrides: $.def(''),
217
+ form_button: $.val(arg.get(['form', 'showButton'])).def(false),
218
+ list_button: $.val(arg.get(['list', 'showButton'])).def(false),
219
+ form_link: $.val(arg.get(['form', 'showLink'])).def(false),
220
+ list_link: $.val(arg.get(['list', 'showLink'])).def(false),
221
+ form_context_menu: $.val(arg.get(['form', 'showContextMenu'])).def(false),
222
+ list_context_menu: $.val(arg.get(['list', 'showContextMenu'])).def(false),
223
+ show_query: $.from('showQuery').toBoolean().def(false),
224
+ show_insert: $.from('showInsert').toBoolean().def(false).def(true),
225
+ show_multiple_update: $.from('showMultipleUpdate').toBoolean().def(false),
226
+ show_update: $.from('showUpdate').toBoolean().def(true),
227
+ list_choice: $.val(arg.get(['list', 'showListChoice'])).def(false),
228
+ list_banner_button: $.val(arg.get(['list', 'showBannerButton'])).def(false),
229
+ list_save_with_form_button: $.val(arg.get(['list', 'showSaveWithFormButton'])).def(false),
230
+ isolate_script: $.from('isolateScript').toBoolean().def(false),
231
+ ui11_compatible: $.val(arg.get(['client', 'isUi11Compatible'])).def(false),
232
+ ui16_compatible: $.val(arg.get(['client', 'isUi16Compatible'])),
233
+ client_script_v2: $.val(arg.get(['workspace', 'clientScriptV2'])),
234
+ form_button_v2: $.val(arg.get(['workspace', 'showFormButtonV2'])).def(false),
235
+ form_menu_button_v2: $.val(arg.get(['workspace', 'showFormMenuButtonV2'])).def(false),
236
+ format_for_configurable_workspace: $.val(arg.get(['workspace', 'isConfigurableWorkspace'])).def(
237
+ false
238
+ ),
239
+ })),
240
+ })
241
+ const roles = arg.get('roles').ifArray()?.getElements() ?? []
242
+ if (!arg.get('condition').toString().getValue().trim() && roles.length === 0) {
243
+ diagnostics.warn(
244
+ arg.get('roles').ifDefined() ?? arg.get('condition').ifDefined() ?? arg,
245
+ 'UI Actions with an empty condition and no roles defined can be called by any logged-in users. Please restrict UI actions. The condition field should be specified to restrict execution of this UI Action to certain users. For example, current.canWrite() condition restricts the UI Action to the users who can modify the current record, gs.hasRole("admin") condition restricts the UI Action to the users with admin role.'
246
+ )
247
+ }
248
+
249
+ if (arg.get('script').is(ModuleFunctionShape) && isClient.ifBoolean()?.getValue()) {
250
+ diagnostics.error(isClient, 'Module scripts (sys_module) cannot be used on client-side UI Actions')
251
+ }
252
+
253
+ const excludeFromViews =
254
+ (arg.get('excludeFromViews').ifArray()?.getElements() as Shape<StringShape>[]) ?? []
255
+ const includeInViews =
256
+ (arg.get('includeInViews').ifArray()?.getElements() as Shape<StringShape>[]) ?? []
257
+ const excludeSet = new Set(excludeFromViews.map((v) => v.getValue()))
258
+ includeInViews.forEach((x) => {
259
+ if (excludeSet.has(x.getValue())) {
260
+ diagnostics.error(
261
+ arg.get('includeInViews'),
262
+ 'The same view should not appear in both the `excludeFromViews` and `includeInViews`'
263
+ )
264
+ }
265
+ })
266
+ const uiActioneViews = [
267
+ ...includeInViews.map((view) =>
268
+ factory.createRecord({
269
+ source: callExpression,
270
+ table: 'sys_ui_action_view',
271
+ properties: {
272
+ sys_ui_action: uiAction.getId(),
273
+ visibility: 'include',
274
+ sys_ui_view: factory.createReference({
275
+ source: view,
276
+ table: 'sys_ui_view',
277
+ keys: { name: view },
278
+ }),
279
+ },
280
+ })
281
+ ),
282
+ ...excludeFromViews.map((view) =>
283
+ factory.createRecord({
284
+ source: callExpression,
285
+ table: 'sys_ui_action_view',
286
+ properties: {
287
+ sys_ui_action: uiAction.getId(),
288
+ visibility: 'exclude',
289
+ sys_ui_view: factory.createReference({
290
+ source: view,
291
+ table: 'sys_ui_view',
292
+ keys: { name: view },
293
+ }),
294
+ },
295
+ })
296
+ ),
297
+ ]
298
+ return {
299
+ 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
+ ),
320
+ }
321
+ },
322
+ },
323
+ ],
324
+ })
@@ -0,0 +1,168 @@
1
+ import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core'
2
+ import { isSNScope } from '@servicenow/sdk-build-core'
3
+ import { XMLParser, XMLBuilder, type X2jOptions, type XmlBuilderOptions } from 'fast-xml-parser'
4
+ import { NowIdShape } from './now-id-plugin'
5
+
6
+ const parserOptions: X2jOptions = {
7
+ ignoreAttributes: false,
8
+ alwaysCreateTextNode: true,
9
+ htmlEntities: true,
10
+ preserveOrder: true,
11
+ attributeNamePrefix: '@_',
12
+ commentPropName: '@_comment',
13
+ processEntities: false,
14
+ }
15
+
16
+ const builderOptions: XmlBuilderOptions = {
17
+ ignoreAttributes: false,
18
+ preserveOrder: true,
19
+ attributeNamePrefix: '@_',
20
+ commentPropName: '@_comment',
21
+ format: true,
22
+ processEntities: true,
23
+ // A valid but undocumented option
24
+ // https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/src/xmlbuilder/json2xml.js#L26
25
+ // @ts-ignore
26
+ entities: [
27
+ // Match on &, &test, but not &amp;, &lt;, &gt;, &apos;, and &quot;
28
+ // See: https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Standard_public_entity_sets_for_characters for the list of default XML entities
29
+ { regex: /&(?!(amp;|lt;|gt;|apos;|quot;))/g, val: '$[AMP]' },
30
+ ],
31
+ }
32
+
33
+ const POLARIS_APPSHELL_THEME_ID = 'c86a62e2c7022010099a308dc7c26022'
34
+
35
+ const parser = new XMLParser(parserOptions)
36
+
37
+ // TODO: Remove this shim tag once we've shipped Glide support for this feature.
38
+ const nowUxGlobals = (themeId: string = POLARIS_APPSHELL_THEME_ID) => {
39
+ return parser.parse(`<!-- @sdk:now-ux-globals -->
40
+ <!-- Resolved from sdk:now-ux-globals tag at NowSDK build time to support earlier Glide releases -->
41
+ <script>
42
+ window.NOW = {};
43
+ window.NOW.user = {};
44
+ window.NOW.batch_glide_ajax_requests = false;
45
+ window.g_ck = "$[gs.getSession().getSessionToken()]";
46
+ </script>
47
+ <!-- Include ServiceNow's required scripts -->
48
+ <g:requires name="scripts/doctype/functions_bootstrap14.js" />
49
+ <g:requires name="scripts/lib/prototype.js" />
50
+ <g:requires name="scripts/classes/ajax/GlideURL.js" />
51
+ <g:requires name="scripts/doctype/CustomEventManager.js" />
52
+ <g:requires name="scripts/classes/ajax/GlideAjax.js" />
53
+ <g:requires name="scripts/classes/GlideUser.js" />
54
+ <g2:client_script type="user" />
55
+ <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>
57
+ <script type="module" src="/uxasset/externals/@devsnc/library-uxf/index.jsdbx"></script>
58
+ <!-- @sdk:now-ux-globals -->
59
+ `)
60
+ }
61
+
62
+ /**
63
+ * Allows us to replace some tags at build time for an improved authoring experience.
64
+ * These are tags that should eventually be supported natively by Glide. These tags
65
+ * should resolve to behavior that will work on earlier versions of Glide in lieu
66
+ * of platform support.
67
+ * @param nodes - parsed XML nodes
68
+ * @returns - parsed XML nodes and any replacements of synthetic tags
69
+ */
70
+ const nodeTransformer = (nodes: any[]) => {
71
+ for (let i = 0; i < nodes.length; i++) {
72
+ const node = nodes[i]
73
+ const tag = Object.keys(node)[0]!
74
+ if (tag === 'sdk:now-ux-globals') {
75
+ const themeId = node[':@']?.['@_theme-id']
76
+ nodes.splice(i, 1, ...nowUxGlobals(themeId))
77
+ continue
78
+ }
79
+ const body = node[tag]
80
+ if (Array.isArray(body)) {
81
+ node[tag] = nodeTransformer(body)
82
+ }
83
+ }
84
+ return nodes
85
+ }
86
+
87
+ export const UiPagePlugin = Plugin.create({
88
+ name: 'UiPagePlugin',
89
+ records: {
90
+ sys_ui_page: {
91
+ toShape(record) {
92
+ return {
93
+ success: true,
94
+ value: new CallExpressionShape({
95
+ source: record,
96
+ callee: 'UiPage',
97
+ args: [
98
+ record.transform(({ $ }) => ({
99
+ $id: $.val(NowIdShape.from(record)),
100
+ category: $.def(''),
101
+ endpoint: $,
102
+ description: $.def(''),
103
+ direct: $.toBoolean().def(false),
104
+ html: $.def(''),
105
+ clientScript: $.from('client_script').def(''),
106
+ processingScript: $.from('processing_script').def(''),
107
+ })),
108
+ ],
109
+ }),
110
+ }
111
+ },
112
+ },
113
+ },
114
+ shapes: [
115
+ {
116
+ shape: CallExpressionShape,
117
+ fileTypes: ['fluent'],
118
+ async toRecord(callExpression, { config, factory, diagnostics }) {
119
+ if (callExpression.getCallee() !== 'UiPage') {
120
+ return { success: false }
121
+ }
122
+
123
+ const arg = callExpression.getArgument(0).asObject()
124
+ const endpoint = arg.get('endpoint').asString()
125
+ const scope = config.scope
126
+ if (scope !== 'global' && !isSNScope(scope) && !endpoint.getValue().startsWith(`${scope}_`)) {
127
+ diagnostics.error(endpoint.getOriginalNode(), `endpoint must begin with '${scope}_'`)
128
+ return { success: false }
129
+ }
130
+ const name = endpoint.asString().getValue().replace(`${scope}_`, '').replace(/\.do$/, '')
131
+ let html = arg.get('html').toString().getValue()
132
+ if (html) {
133
+ try {
134
+ const nodes = parser.parse(html)
135
+ const transformed = nodeTransformer(nodes)
136
+ html = new XMLBuilder(builderOptions).build(transformed)
137
+ } catch (error: unknown) {
138
+ if (error instanceof Error) {
139
+ diagnostics.error(arg.get('html'), error.message)
140
+ } else {
141
+ diagnostics.error(arg.get('html'), `html must be valid`)
142
+ }
143
+ return { success: false }
144
+ }
145
+ }
146
+
147
+ return {
148
+ success: true,
149
+ value: factory.createRecord({
150
+ source: callExpression,
151
+ table: 'sys_ui_page',
152
+ explicitId: arg.get('$id'),
153
+ properties: arg.transform(({ $ }) => ({
154
+ name: $.val(name),
155
+ endpoint: $.val(endpoint),
156
+ description: $,
157
+ direct: $.def(false),
158
+ category: $,
159
+ html: $.val(html).toCdata(),
160
+ client_script: $.from('clientScript').toCdata(),
161
+ processing_script: $.from('processingScript').toCdata(),
162
+ })),
163
+ }),
164
+ }
165
+ },
166
+ },
167
+ ],
168
+ })
@@ -0,0 +1,62 @@
1
+ import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core'
2
+ import { NowIdShape } from './now-id-plugin'
3
+
4
+ /**
5
+ * Creates a User Preference (sys_user_preference).
6
+ *
7
+ * @see https://docs.servicenow.com/csh?topicname=c_UserPreferences.html&version=latest
8
+ *
9
+ * @param config - an object containing the following properties:
10
+ * * **$id** - unique id for the record, typically using `Now.ID["value"]`
11
+ * * **name** - name of the feature or functionality
12
+ * * **type** - the data type of entry accepted for the `value`
13
+ * * **value** - current setting for this record
14
+ * * **description**? - short description of the feature or functionality
15
+ * * **system**? - whether this record indicates the system-wide default
16
+ */
17
+ export const UserPreferencePlugin = Plugin.create({
18
+ name: 'UserPreferencePlugin',
19
+ records: {
20
+ sys_user_preference: {
21
+ toShape(record) {
22
+ return {
23
+ success: true,
24
+ value: new CallExpressionShape({
25
+ source: record,
26
+ callee: 'UserPreference',
27
+ args: [
28
+ record.transform(({ $, merge }) => ({
29
+ $id: $.val(NowIdShape.from(record)),
30
+ system: $.from('system').toBoolean(),
31
+ [merge]: $,
32
+ })),
33
+ ],
34
+ }),
35
+ }
36
+ },
37
+ },
38
+ },
39
+ shapes: [
40
+ {
41
+ shape: CallExpressionShape,
42
+ fileTypes: ['fluent'],
43
+ toRecord(callExpression, { factory }) {
44
+ if (callExpression.getCallee() !== 'UserPreference') {
45
+ return { success: false }
46
+ }
47
+
48
+ const pref = callExpression.getArgument(0).asObject()
49
+
50
+ return {
51
+ success: true,
52
+ value: factory.createRecord({
53
+ source: callExpression,
54
+ table: 'sys_user_preference',
55
+ explicitId: pref.get('$id'),
56
+ properties: pref.pick(['name', 'type', 'value', 'description', 'system']),
57
+ }),
58
+ }
59
+ },
60
+ },
61
+ ],
62
+ })
package/src/utils.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { ts, type Shape, type ObjectShape, type Diagnostics } from '@servicenow/sdk-build-core'
2
+
3
+ export function toReference(shape: Shape) {
4
+ return shape.ifRecord()?.getId() ?? shape.ifString()?.getValue() ?? ''
5
+ }
6
+
7
+ /**
8
+ * Reverses an object, swapping keys and values. **reverseObject** should only be used
9
+ * where the key/values are all known ahead of time and the values are unique.
10
+ * @example
11
+ * reverseObject({ a: 'foo', b: 'bar' }) // { foo: 'a', bar: 'b' }
12
+ */
13
+ export function reverseObject<K extends string, V extends string>(obj: Record<K, V>) {
14
+ const reversed = {} as Record<V, K>
15
+ for (const key in obj) {
16
+ const value = obj[key]
17
+ if (typeof value === 'string') {
18
+ reversed[value] = key
19
+ }
20
+ }
21
+ return reversed
22
+ }
23
+
24
+ export function noThrow<T>(action: () => T) {
25
+ try {
26
+ return action()
27
+ } catch (error) {
28
+ return error as Error
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Regex taken from: https://github.com/oozcitak/xmlbuilder-js/blob/b20136cd1591d0f17ab2f184053c7150150428b2/src/XMLStringifier.coffee#L119C15-L119C127
34
+ */
35
+ export const INVALID_XML_CHARACTERS =
36
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: This is intentional
37
+ /[\0-\x08\x0B\f\x0E-\x1F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/g
38
+
39
+ export function applyPathMappings(path: string, mappings: Record<string, string>) {
40
+ if (!mappings) {
41
+ return path
42
+ }
43
+ // TODO: Naive implementation for now that just supports simple patterns. We can explore supporting more complex patterns later.
44
+ for (const [source, target] of Object.entries(mappings)) {
45
+ const match = path.match(`${source.replace(/\./, '\\.').replace(/\*+/, '(.*)')}$`)?.[1]
46
+ if (match !== undefined) {
47
+ return target.replace(/\*+/, match)
48
+ }
49
+ }
50
+ return path
51
+ }
52
+
53
+ export function getCallExpressionName(node: ts.CallExpression) {
54
+ const expression = node.getExpression()
55
+ if (ts.Node.isIdentifier(expression) || ts.Node.isPropertyAccessExpression(expression)) {
56
+ return expression.getText()
57
+ }
58
+
59
+ throw `CallExpression does not have a name: ${expression.getText()}`
60
+ }
61
+
62
+ export function generateDeprecatedDiagnostics(object: ObjectShape, diagnostics: Diagnostics): void {
63
+ Object.keys(object.getAliasedKeys()).forEach((key) => {
64
+ const alias = object.findAliasUsed(key)
65
+ if (alias) {
66
+ diagnostics.hint(object.get(key), `The property '${alias}' is deprecated, use '${key}' instead.`)
67
+ }
68
+ })
69
+ }
@@ -0,0 +1,46 @@
1
+ import { Plugin, Record, RecordId, Shape } from '@servicenow/sdk-build-core'
2
+
3
+ export const ViewPlugin = Plugin.create({
4
+ name: 'ViewPlugin',
5
+ records: {
6
+ sys_ui_view: {
7
+ coalesce: ['name'],
8
+ },
9
+ },
10
+ shapes: [
11
+ {
12
+ shape: Record,
13
+ inspect(record, { diagnostics }) {
14
+ if (record.getTable() !== 'sys_ui_view') {
15
+ return
16
+ }
17
+
18
+ if (record.get('title').equals('Default view')) {
19
+ // The default view's name will be empty, so skip the validation
20
+ return
21
+ }
22
+
23
+ const viewName = record.get('name')
24
+ if (!viewName.isString() || !/^[a-zA-Z0-9_]+$/.test(viewName.getValue())) {
25
+ diagnostics.error(viewName.getOriginalNode(), `View name can only contain alphanumeric characters`)
26
+ }
27
+ },
28
+ },
29
+ {
30
+ shape: RecordId,
31
+ async commit(id, target, { commit }) {
32
+ if (id.getTable() !== 'sys_ui_view') {
33
+ return { success: false }
34
+ }
35
+
36
+ const viewName = id.getKey('name')
37
+ if (!viewName) {
38
+ return { success: false }
39
+ }
40
+
41
+ await commit(Shape.from(id, viewName).asString(), target)
42
+ return { success: true }
43
+ },
44
+ },
45
+ ],
46
+ })