@servicenow/sdk-build-plugins 3.0.3 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +39 -0
  11. package/dist/atf/step-configs.js +2334 -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 +600 -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 +164 -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 +2384 -0
  136. package/src/atf/test-plugin.ts +739 -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 +179 -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 +658 -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
@@ -1,2072 +0,0 @@
1
- import {
2
- ChoiceConfig,
3
- Table,
4
- Record as NowRecord,
5
- TableName,
6
- choiceDropdown,
7
- DateColumn,
8
- BasicDateTimeColumn,
9
- GenericColumn,
10
- BooleanColumn,
11
- ChoiceColumn,
12
- IntegerDateColumn,
13
- ScheduleDateTimeColumn,
14
- ConditionsColumn,
15
- DateTimeColumn,
16
- CalendarDateTimeColumn,
17
- DueDateColumn,
18
- OtherDateColumn,
19
- DecimalColumn,
20
- DocumentIdColumn,
21
- DomainIdColumn,
22
- DomainPathColumn,
23
- FieldNameColumn,
24
- IntegerColumn,
25
- RadioColumn,
26
- ReferenceColumn,
27
- ScriptColumn,
28
- SystemClassNameColumn,
29
- TableNameColumn,
30
- TranslatedFieldColumn,
31
- TranslatedTextColumn,
32
- UserRolesColumn,
33
- VersionColumn,
34
- StringColumn,
35
- Documentation,
36
- ListColumn,
37
- BasicImageColumn,
38
- } from '@servicenow/sdk-core/runtime/db'
39
- import {
40
- Context,
41
- EntityData,
42
- LinkedDocument,
43
- Plugin,
44
- extractCallExpression,
45
- getCallExpressionName,
46
- getOrCreateEntitySourceFile,
47
- getOrCreatePropertyAssignment,
48
- linkDocument,
49
- removeNode,
50
- stringify,
51
- transformFunctionArguments,
52
- XmlData,
53
- FluentDiagnostic,
54
- generateCallExpression,
55
- createPropertyIdentifier,
56
- ObjectData,
57
- isSNScope,
58
- GUID,
59
- mergeDataIntoObjectLiteral,
60
- getPropertyAssignment,
61
- mergeDataIntoObjectLiteralArray,
62
- addNamedImportIfAbsent,
63
- generateCallExpressionExportForDocument,
64
- Document,
65
- generateCallExpressionExport,
66
- PartialElements,
67
- getObjectPropertyAssignmentName,
68
- } from '@servicenow/sdk-build-core'
69
- import { create } from 'xmlbuilder2'
70
- import { isArray, isEmpty, isObject, parseInt } from 'lodash'
71
- import { z } from 'zod'
72
- import { RecordPlugin, TextBooleanSchema, TextNumberSchema, TextStringSchema } from './RecordPlugin'
73
- import { Diagnostic, ts, tsc } from '@servicenow/sdk-project'
74
- import { XMLBuilder } from 'xmlbuilder2/lib/interfaces'
75
- import { getLabelDiagnostics } from './DBUtils'
76
- import { ModuleFunctionData } from '../ServerModulePlugin'
77
-
78
- /**
79
- * The access levels are mapped to the following values on the platform
80
- *
81
- * - `none`: 0
82
- * - `tracking`: 1
83
- * - `restricted`: 2
84
- *
85
- */
86
- const callerAccess = ['none', 'tracking', 'restricted'] as const
87
-
88
- // Basic info needed for table references
89
- const TableSchemaFull = z.object({
90
- /** lowercase, one word name. Numbers, letters and underscores only */
91
- name: z.string(),
92
- /** Object literal of column names with <type>Column() calls as values.
93
- * Ex. { column_name_1: StringColumn({...args}), column_name_2: IntegerColumn({...args}), }
94
- * Import column definitions from `@servicenow/sdk-core/db`
95
- */
96
- schema: z.record(z.record(z.any())).default({}),
97
- /** Table as a string, this table will inherit schema from extends table.
98
- * Escape with `` (import from `@servicenow/sdk-core/global`)
99
- * if table definition not present locally */
100
- extends: z.string().optional(),
101
- /** Will match name if not provided */
102
- label: z.string().or(z.array(z.any())).optional(),
103
- /** Must match column name */
104
- display: z.string().optional(),
105
-
106
- // Controls
107
- extensible: z.boolean().optional().default(false),
108
- live_feed: z.boolean().optional().default(false),
109
-
110
- /** sys_number to create auto prefixing. Specify as Object literal */
111
- auto_number: z
112
- .object({
113
- prefix: z.string().default('pre').optional(),
114
- number: z.number().default(1000).optional(),
115
- number_of_digits: z.number().default(7).optional(),
116
- })
117
-
118
- .optional(),
119
-
120
- // Application Access
121
- accessible_from: z
122
- .union([z.literal('package_private'), z.literal('public')])
123
- .optional()
124
- .default('public'),
125
- caller_access: z.enum(callerAccess).optional(),
126
- /** Array of read, update, create, delete actions (['read', 'update',...])*/
127
- actions: z
128
- .array(z.union([z.literal('read'), z.literal('update'), z.literal('delete'), z.literal('create')]))
129
- .optional(),
130
-
131
- allow_web_service_access: z.boolean().optional().default(false),
132
- allow_new_fields: z.boolean().optional().default(false),
133
- allow_ui_actions: z.boolean().optional().default(false),
134
- allow_client_scripts: z.boolean().optional().default(false),
135
-
136
- // From sys_dictionary
137
- audit: z.boolean().optional().default(false),
138
- read_only: z.boolean().optional().default(false),
139
- text_index: z.boolean().optional().default(false),
140
-
141
- /** Object literal of key value pairs corresponding to attributes */
142
- attributes: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
143
-
144
- /** Array of objects [{ { name: <columnName>, element: ...,}...}] */
145
- index: z
146
- .array(
147
- z.object({
148
- name: z.string(),
149
- unique: z.boolean(),
150
- element: z
151
- .string()
152
- .or(z.array(z.string()))
153
- .transform((el) => (isArray(el) ? el : [el])),
154
- })
155
- )
156
- .optional(),
157
-
158
- licensing_config: z.record(z.any()).optional(),
159
- scriptable_table: z.boolean().default(false),
160
- })
161
-
162
- const componentTables = ['sys_dictionary', 'sys_choice', 'sys_documentation', 'ua_table_licensing_config']
163
-
164
- type IndexType = {
165
- name: string
166
- unique: boolean
167
- element: string[] | string
168
- }
169
-
170
- // Everything that goes into a table
171
- // Everything which goes into a element with type='string/int/etc' in bootstrap.xml
172
- type ColumnSchema = z.infer<typeof ColumnSchema>
173
- const ColumnSchema = z.object({
174
- entityKind: z.string().optional(),
175
- column_type: z.string().optional(),
176
- audit: z.boolean().optional().default(false),
177
- label: z.string().or(z.array(z.any())).optional(),
178
- maxLength: z.number().optional(),
179
- mandatory: z.boolean().optional().default(false),
180
- read_only: z.boolean().optional().default(false),
181
- default: z.any().optional(),
182
- attributes: z.record(z.string(), z.union([z.string(), z.boolean(), z.number()])).optional(),
183
- referenceTable: z.string().optional(),
184
- cascadeRule: z.string().optional(),
185
- dropdown: z.enum(choiceDropdown).default('none').optional(),
186
- choices: z.record(z.any()).or(z.array(z.any())).optional(),
187
- choice_elements: z.record(z.any()).or(z.array(z.any())).optional(),
188
- display: z.boolean().default(false).optional(),
189
- function_definition: z.string().optional(),
190
- dynamic_value_definitions: z
191
- .object({
192
- type: z.union([
193
- z.literal('dynamic_default'),
194
- z.literal('choices_from_other_table'),
195
- z.literal('calculated_value'),
196
- z.literal('dependent_field'),
197
- ]),
198
- })
199
- .and(z.any())
200
- .optional(),
201
- plural: z.string().optional(),
202
- hint: z.string().optional(),
203
- help: z.string().optional(),
204
- widget: z.string().optional(),
205
- table_reference: z.boolean().optional(),
206
- reference_floats: z.boolean().optional(),
207
- dynamic_creation: z.boolean().optional(),
208
- dynamic_creation_script: z.string().optional(),
209
- element_reference: z.boolean().optional(),
210
- spell_check: z.boolean().optional(),
211
- xml_view: z.boolean().optional(),
212
- array: z.boolean().optional(),
213
- text_index: z.boolean().optional(),
214
- primary: z.boolean().optional(),
215
- unique: z.boolean().optional(),
216
- reference_key: z.string().optional(),
217
- reference_qual: z.string().optional(),
218
- })
219
-
220
- const BooleanFromString = z
221
- .string()
222
- .transform((str) => str === 'true')
223
- .or(z.boolean())
224
- .optional()
225
-
226
- const IntFromString = z
227
- .string()
228
- .transform((str) => parseInt(str))
229
- .or(z.number())
230
- .optional()
231
-
232
- // These fields transform from sys_db_object only, not bootstrap. (Except name, which is needed to match)
233
- const DBObjectIncomingAttributes = z.object({
234
- name: TextStringSchema.or(z.string()).optional(),
235
-
236
- read_access: TextBooleanSchema.or(BooleanFromString).optional(),
237
- create_access: TextBooleanSchema.or(BooleanFromString).optional(),
238
- update_access: TextBooleanSchema.or(BooleanFromString).optional(),
239
- delete_access: TextBooleanSchema.or(BooleanFromString).optional(),
240
-
241
- ws_access: TextBooleanSchema.or(BooleanFromString).optional(),
242
- caller_access: TextNumberSchema.or(IntFromString)
243
- .transform((val) => {
244
- if (val) {
245
- return callerAccess[val]
246
- }
247
- return
248
- })
249
- .optional(),
250
- alter_access: TextBooleanSchema.or(BooleanFromString).optional(),
251
- client_scripts_access: TextBooleanSchema.or(BooleanFromString).optional(),
252
- actions_access: TextBooleanSchema.or(BooleanFromString).optional(),
253
- //configuration_access: TextBooleanSchema.or(BooleanFromString).optional().default(false),
254
-
255
- is_extendable: TextBooleanSchema.or(BooleanFromString).optional(),
256
- // live_feed_enabled: TextBooleanSchema.or(BooleanFromString).optional().default(false),
257
-
258
- access: TextStringSchema.or(z.string()).optional(),
259
-
260
- scriptable_table: TextBooleanSchema.or(BooleanFromString).optional(),
261
- })
262
-
263
- // Attributes in the element='collection' tag of bootstrap xml
264
- const TableSchemaBootstrap = z.object({
265
- name: z.string(),
266
- extends: z.string().optional(),
267
- label: z.string().or(z.array(z.any())).optional(),
268
-
269
- // Controls
270
- extensible: z.boolean().optional().default(false),
271
- live_feed: z.boolean().optional().default(false),
272
-
273
- auto_number: z
274
- .object({
275
- prefix: z.string().default('pre').optional(),
276
- number: z.number().default(1000).optional(),
277
- number_of_digits: z.number().default(7).optional(),
278
- })
279
- .optional(),
280
-
281
- number_ref: z.any().optional(),
282
-
283
- // Application Access
284
- accessible_from: z
285
- .union([z.literal('public'), z.literal('package_private')])
286
- .optional()
287
- .default('public'),
288
- caller_access: z.enum(callerAccess).default('none').optional(),
289
-
290
- actions: z
291
- .array(z.union([z.literal('read'), z.literal('update'), z.literal('delete'), z.literal('create')]))
292
- .default(['read'])
293
- .optional(),
294
-
295
- allow_web_service_access: z.boolean().optional().default(true),
296
- allow_new_fields: z.boolean().optional().default(false),
297
- allow_ui_actions: z.boolean().optional().default(false),
298
- allow_client_scripts: z.boolean().optional().default(false),
299
-
300
- // From sys_dictionary
301
- audit: z.boolean().optional().default(false),
302
- read_only: z.boolean().optional().default(false),
303
- text_index: z.boolean().optional().default(false),
304
-
305
- scriptable_table: z.boolean().optional().default(false),
306
-
307
- attributes: z
308
- .record(z.union([z.string(), z.number(), z.boolean()]))
309
- .default({})
310
- .optional(),
311
- })
312
-
313
- const TableSchemaBootstrapIncoming = TableSchemaBootstrap.omit({ actions: true }).extend({
314
- caller_access: z
315
- .union([z.literal(0), z.literal(1), z.literal(2)])
316
- .transform((val) => {
317
- if (val) {
318
- return callerAccess[val]
319
- }
320
- return
321
- })
322
- .optional(),
323
- accessible_from: z.union([z.literal('public'), z.literal('package_private')]).optional(),
324
- extends: z
325
- .string()
326
- .or(z.object({ name: z.string() }).transform((obj) => obj.name))
327
- .optional(),
328
- live_feed: z.boolean().optional().default(false),
329
- index: z.any().optional(),
330
- columns: z.any().optional(),
331
- })
332
-
333
- // Everything in side <database> in boostrap.xml
334
- const BootstrapDatabaseElement = z.object({
335
- element: z.record(z.any()),
336
- })
337
-
338
- const DBObjectIncoming = z.object({
339
- '@_table': z.literal('sys_db_object'),
340
- sys_db_object: z.record(z.any()),
341
- })
342
-
343
- const SysDocumentation = z.object({
344
- sys_documentation: z.object({
345
- element: TextStringSchema.optional(),
346
- label: TextStringSchema.optional(),
347
- language: TextStringSchema.optional(),
348
- hint: TextStringSchema.optional(),
349
- help: TextStringSchema.optional(),
350
- name: TextStringSchema.optional(),
351
- plural: TextStringSchema.optional(),
352
- sys_id: TextStringSchema.optional(),
353
- url: TextStringSchema.optional(),
354
- url_target: TextStringSchema.optional(),
355
- }),
356
- })
357
-
358
- const LicensingConfig = z.object({
359
- ua_table_licensing_config: z.object({
360
- name: TextStringSchema.optional(),
361
- op_insert: TextBooleanSchema.optional(),
362
- op_update: TextBooleanSchema.optional(),
363
- op_delete: TextBooleanSchema.optional(),
364
- is_fulfillment: TextBooleanSchema.optional(),
365
- license_model: TextStringSchema.optional(),
366
- owner_condition: TextStringSchema.optional(),
367
- license_condition: TextStringSchema.optional(),
368
- license_roles: TextStringSchema.optional(),
369
- }),
370
- })
371
-
372
- // Attributes from element=table in bootstrap.xml
373
- const TableSchemaBootstrapAttributes = z
374
- .object({
375
- '@_name': z.string(),
376
- '@_extends': z.string().optional(),
377
- '@_label': z.string().optional(),
378
- '@_max_length': z.any().optional(),
379
-
380
- // From sys_dictionary/sys_db_object
381
- '@_audit': BooleanFromString,
382
- '@_read_only': BooleanFromString,
383
- '@_text_index': BooleanFromString,
384
- '@_client_scripts_access': BooleanFromString,
385
- '@_ws_access': BooleanFromString,
386
- '@_alter_access': BooleanFromString,
387
- '@_create_access': BooleanFromString,
388
- '@_delete_access': BooleanFromString,
389
- '@_update_access': BooleanFromString,
390
- '@_query_access': BooleanFromString,
391
- '@_actions_access': BooleanFromString,
392
- '@_read_access': BooleanFromString,
393
- '@_is_extendable': BooleanFromString,
394
- '@_caller_access': IntFromString,
395
- '@_scriptable_table': BooleanFromString,
396
-
397
- '@_attributes': z
398
- .string()
399
- .transform((values) => {
400
- const ret = {}
401
- if (values === '') {
402
- return undefined
403
- }
404
- const entries = values.split(',')
405
- entries.forEach((attr) => {
406
- const s = attr.split('=')
407
- if (s.length === 2 && s[0] && s[1]) {
408
- try {
409
- ret[s[0]] = JSON.parse(s[1])
410
- } catch (err) {
411
- ret[s[0]] = s[1]
412
- }
413
- }
414
- })
415
- return ret
416
- })
417
- .optional(),
418
- })
419
- .catchall(z.any())
420
-
421
- const DictionaryXmlSchema = z.object({
422
- sys_dictionary: z
423
- .object({
424
- '@_action': z.union([z.literal('INSERT_OR_UPDATE'), z.literal('DELETE'), z.literal('delete_multiple')]),
425
- sys_id: z
426
- .object({
427
- '#text': z.string().min(32).max(32).or(z.number()),
428
- })
429
- .transform((val) => val['#text'])
430
- .optional(),
431
- '@_element': z.string(),
432
- '@_table': z.string(),
433
- })
434
- .catchall(
435
- z
436
- .object({
437
- '#text': z.union([z.string(), z.boolean(), z.number(), z.undefined()]),
438
- })
439
- .transform((val) => val['#text'])
440
- ),
441
- })
442
-
443
- const IndexSchemaBootstrapAttributes = z.object({
444
- '@_name': z.string(),
445
- '@_unique': BooleanFromString,
446
- element: z.object({ '@_name': z.string() }).or(
447
- z.array(
448
- z.object({
449
- '@_name': z.string(),
450
- })
451
- )
452
- ),
453
- })
454
-
455
- const ColumnSchemaBootstrapAttributes = TableSchemaBootstrapAttributes.omit({ '@_extends': true })
456
- .extend({
457
- '@_choice': z.coerce.number().optional(),
458
- '@_active': BooleanFromString,
459
- '@_mandatory': BooleanFromString,
460
- '@_display': BooleanFromString,
461
- '@_type': z.string().optional(),
462
- '@_use_dependent_field': BooleanFromString,
463
- '@_use_dynamic_default': BooleanFromString,
464
- '@_reference': z.string().optional(),
465
- '@_virtual': BooleanFromString,
466
- '@_default': z.string().optional(),
467
- '@_calculation': z.string().optional(),
468
- '@_choice_field': z.string().optional(),
469
- '@_function_definition': z.string().optional(),
470
- '@_reference_floats': BooleanFromString,
471
- '@_reference_key': z.string().optional(),
472
- '@_dynamic_creation_script': z.string().optional(),
473
- '@_dynamic_creation': BooleanFromString,
474
- '@_plural': z.string().optional(),
475
- '@_hint': z.string().optional(),
476
- '@_help': z.string().optional(),
477
- '@_widget': z.string().optional(),
478
- '@_table_reference': BooleanFromString,
479
- '@_element_reference': BooleanFromString,
480
- '@_unique': BooleanFromString,
481
- '@_spell_check': BooleanFromString,
482
- '@_xml_view': BooleanFromString,
483
- '@_array': BooleanFromString,
484
- '@_text_index': BooleanFromString,
485
- '@_primary': BooleanFromString,
486
- '@_reference_qual': z.string().optional(),
487
- choice: z.object({ element: z.array(z.any()).or(z.record(z.any())).optional() }).optional(),
488
- '@_attributes': z
489
- .string()
490
- .transform((values) => {
491
- const ret = {}
492
- if (values === '') {
493
- return undefined
494
- }
495
- const entries = values.split(',')
496
- entries.forEach((attr) => {
497
- const s = attr.split('=')
498
- if (s.length === 2 && s[0] && s[1]) {
499
- try {
500
- ret[s[0]] = JSON.parse(s[1])
501
- } catch (err) {
502
- ret[s[0]] = s[1]
503
- }
504
- }
505
- })
506
- return ret
507
- })
508
- .optional(),
509
- })
510
- .catchall(z.any())
511
-
512
- const ChoiceSchema = z.object({
513
- label: z.string().optional(),
514
- value: z.string().optional(),
515
- sequence: z.coerce.number().optional(),
516
- dependent_value: z.coerce.number().or(z.string()).optional(),
517
- hint: z.string().optional(),
518
- inactive: BooleanFromString.default(false).optional(),
519
- inactive_on_update: BooleanFromString.default(false).optional(),
520
- language: z.string().optional(),
521
- })
522
-
523
- const ChoiceSchemaIncoming = ChoiceSchema.omit({ value: true })
524
-
525
- function composeLicenseConfig(tableName: string, config, node) {
526
- return {
527
- kind: 'ua_table_licensing_config',
528
- guid: `${tableName}_license`,
529
- data: {
530
- table: 'ua_table_licensing_config',
531
- $id: tableName,
532
- data: {
533
- name: tableName,
534
- op_insert: config.op_insert ?? true,
535
- op_update: config.op_update ?? true,
536
- op_delete: config.op_delete ?? true,
537
- is_fulfillment: config.is_fulfillment ?? false,
538
- license_model: config.license_model ?? 'none',
539
- owner_condition: config.owner_condition ?? '',
540
- license_condition: config.license_condition ?? '',
541
- license_roles: config.license_roles ? config.license_roles.join(',') : '',
542
- },
543
- },
544
- node,
545
- }
546
- }
547
-
548
- type ComposedTableData = {
549
- data: {
550
- bootstrapData: any
551
- dbObjectData: any
552
- }
553
- }
554
-
555
- const tableNameRegex = new RegExp(`^[a-z_][a-z0-9_]*[a-z0-9]$`)
556
-
557
- export default Plugin({
558
- name: 'Table',
559
- ownedTables: {
560
- sys_db_object: { diagnosticLevel: Diagnostic.Level.Warn },
561
- },
562
- extractors: {
563
- entity: {
564
- fluent: {
565
- // TODO: Cast to `any` is temporary workaround for the circular nature of Table entities
566
- CallExpression: (node, context) => {
567
- const result = extractCallExpression(Table, 'table', node, context, (table) => table.name)
568
- if (!result.handled || !result.data) {
569
- return result
570
- }
571
-
572
- const data = result.data
573
- const diagnostics = result.diagnostics
574
- const scopeName = context.app.config.scope
575
- const scopeRegex = new RegExp(`^${scopeName}_`)
576
- const columnNameRegex = new RegExp(`^[a-z_][a-z0-9_]*$`)
577
- const tableName = data.getProperty('name')
578
- const scopeMatches = tableName.getValue().match(scopeRegex)
579
- let ignoreColumnNameCheck = false
580
-
581
- if (!tableName.getValue().match(tableNameRegex)) {
582
- diagnostics.push(
583
- new FluentDiagnostic(
584
- tableName.getNode(),
585
- `Table name must only contain lowercase letters, numbers, and underscores and end with a letter or number`
586
- )
587
- )
588
- }
589
-
590
- if (!scopeMatches) {
591
- const nameNode = tableName.getNode().asKindOrThrow(ts.SyntaxKind.StringLiteral)
592
- if (nameNode.getParent().getKindName() !== 'AsExpression') {
593
- diagnostics.push(
594
- new FluentDiagnostic(
595
- tableName.getNode(),
596
- `'name' property must start with scope prefix '${scopeName}'`
597
- )
598
- )
599
- } else {
600
- ignoreColumnNameCheck = true
601
- }
602
- }
603
-
604
- const schema = data.getProperty('schema')
605
- const schemaNode = schema.getNode().asKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression)
606
- for (const columnName in schema.getValue()) {
607
- const columnNode = schemaNode.getPropertyOrThrow(columnName)
608
- if (
609
- !ignoreColumnNameCheck &&
610
- !scopeMatches &&
611
- !isSNScope(scopeName) &&
612
- !columnName.match(scopeRegex)
613
- ) {
614
- diagnostics.push(
615
- new FluentDiagnostic(
616
- columnNode,
617
- `Column name must be prefixed with scope '${scopeName}' if table name does not contain prefix`
618
- )
619
- )
620
- }
621
-
622
- if (!columnName.match(columnNameRegex)) {
623
- diagnostics.push(
624
- new FluentDiagnostic(
625
- columnNode,
626
- `Column name must only contain lowercase letters, numbers, and underscores`
627
- )
628
- )
629
- }
630
- }
631
-
632
- const declaration = node.getParentIfKind(ts.SyntaxKind.VariableDeclaration)
633
- if (
634
- !declaration ||
635
- !declaration.isExported() ||
636
- !declaration.isNamedExport() ||
637
- declaration.getName() !== tableName.getValue()
638
- ) {
639
- diagnostics.push(
640
- new FluentDiagnostic(
641
- node,
642
- `Table definition should be exported as a named export with the name '${tableName.getValue()}'`,
643
- { level: Diagnostic.Level.Warn }
644
- )
645
- )
646
- }
647
-
648
- diagnostics.push(...getLabelDiagnostics(data))
649
- const entityData = new EntityData(
650
- 'table',
651
- tableName.getValue(),
652
- new ObjectData(data.getProperties(), data.getNode()),
653
- data.getNode(),
654
- data.getInstallMethod(),
655
- [tableName.getValue()]
656
- )
657
- return { handled: true, data: entityData, diagnostics }
658
- },
659
- },
660
- },
661
- xml(xml, context) {
662
- const bootstrapData = {}
663
- let dbObjectData = {}
664
- const bootstrapDatabaseXML = BootstrapDatabaseElement.safeParse(xml.data['database'])
665
- if (bootstrapDatabaseXML.success) {
666
- const data = TableSchemaBootstrapAttributes.parse(bootstrapDatabaseXML.data.element)
667
- Object.entries(data).forEach(([key, value]) => {
668
- if (key.startsWith('@_')) {
669
- bootstrapData[key.substring(2)] = value
670
- } else if (key === 'element') {
671
- //
672
- } else {
673
- bootstrapData[key] = value
674
- }
675
- })
676
- context.updateHandledXMLs(xml.filePath, 'handled')
677
- }
678
-
679
- const db_object_inc = DBObjectIncoming.safeParse(xml.data['record_update'])
680
- if (db_object_inc.success) {
681
- dbObjectData = DBObjectIncomingAttributes.parse(db_object_inc.data.sys_db_object)
682
- context.updateHandledXMLs(xml.filePath, 'handled')
683
- return new XmlData(
684
- dbObjectData,
685
- xml.filePath,
686
- 'sys_db_object',
687
- db_object_inc.data.sys_db_object['@_action']
688
- )
689
- } else if (!bootstrapDatabaseXML.success) {
690
- const record_update = xml.data['record_update']
691
- if (record_update) {
692
- const table = Object.keys(record_update)[0]
693
- if (!table || !componentTables.includes(table)) {
694
- return
695
- }
696
-
697
- if (table === 'sys_documentation') {
698
- const data = SysDocumentation.parse(record_update[table]).sys_documentation
699
- return new XmlData(
700
- {
701
- table: table,
702
- id: record_update[table][table]['sys_id']?.['#text'] ?? GUID(),
703
- data,
704
- },
705
- xml.filePath,
706
- 'sys_documentation',
707
- record_update[table]['@_action']
708
- )
709
- }
710
-
711
- if (table === 'ua_table_licensing_config') {
712
- const data = LicensingConfig.parse(record_update).ua_table_licensing_config
713
- return new XmlData(
714
- {
715
- table: table,
716
- id: record_update[table]['sys_id']?.['#text'] ?? GUID(),
717
- data,
718
- },
719
- xml.filePath,
720
- 'ua_table_licensing_config',
721
- record_update[table]['@_action']
722
- )
723
- }
724
-
725
- const data = DictionaryXmlSchema.safeParse(record_update)
726
- if (data.success) {
727
- const {
728
- '@_action': action,
729
- '@_element': element,
730
- '@_table': dictTable,
731
- sys_id,
732
- ...dict
733
- } = data.data.sys_dictionary
734
- return new XmlData(
735
- {
736
- table: table,
737
- id: sys_id ?? `${dict['name']}_${dict['element'] !== '' ? dict['element'] : '_null'}`,
738
- data: dict,
739
- },
740
- xml.filePath,
741
- 'sys_dictionary',
742
- action
743
- )
744
- }
745
- context.updateHandledXMLs(xml.filePath, 'ignored')
746
- return
747
- }
748
- }
749
-
750
- // Columns and Indexes
751
- const columns: z.infer<typeof ColumnSchemaBootstrapAttributes>[] = []
752
- const idxElements: IndexType[] = []
753
- if (bootstrapDatabaseXML.success && bootstrapDatabaseXML.data.element['element']) {
754
- const element = bootstrapDatabaseXML.data.element['element']
755
- const elementsArray = isArray(element) ? element : [element]
756
- columns.push(...z.array(ColumnSchemaBootstrapAttributes).parse(elementsArray))
757
-
758
- columns.forEach((element) => {
759
- if (element.choice && !isEmpty(element.choice)) {
760
- element['choice_elements'] = {}
761
- const choices = isArray(element.choice.element)
762
- ? element.choice.element
763
- : [element.choice.element]
764
- choices.forEach((choice) => {
765
- const obj = removeAttributeTag(choice)
766
- const choiceData = ChoiceSchemaIncoming.parse(obj)
767
- if (!choiceData.label) {
768
- choiceData.label = obj.value
769
- }
770
- element['choice_elements'][obj.value] = choiceData
771
- })
772
- }
773
-
774
- element = removeAttributeTag(element)
775
- })
776
- bootstrapData['columns'] = columns.reduce((map, obj) => ((map[obj['name']] = obj), map), {})
777
-
778
- let elements = bootstrapDatabaseXML.data.element['index']
779
- elements = isArray(elements) ? elements : [elements]
780
- elements.forEach((element) => {
781
- const idxData = IndexSchemaBootstrapAttributes.safeParse(element)
782
- if (idxData.success) {
783
- idxElements.push({
784
- name: idxData.data['@_name'],
785
- element: isArray(idxData.data.element)
786
- ? idxData.data.element.reduce((arr, curr) => {
787
- arr.push(curr['@_name'])
788
- return arr
789
- }, [] as string[])
790
- : idxData.data.element['@_name'],
791
- unique: idxData.data['@_unique'] ?? false,
792
- })
793
- }
794
- })
795
- bootstrapData['index'] = idxElements
796
- }
797
-
798
- return new XmlData(bootstrapData, xml.filePath, 'bootstrap')
799
- },
800
- },
801
- composers: {
802
- entity: {
803
- async table(entity, context) {
804
- const node = entity.getNode()
805
- const data = entity.getValue()
806
- const table = TableSchemaFull.parse(data)
807
-
808
- const composeData = compose(table)
809
- const { columnData, documentation } = composeColumns(
810
- table.schema as Record<string, ColumnSchema>,
811
- context,
812
- table.name,
813
- table.display
814
- )
815
-
816
- composeData['columns'] = columnData
817
-
818
- const entities: LinkedDocument[] = []
819
- if (table.auto_number) {
820
- const data = table.auto_number
821
-
822
- const numberRecord = SysNumber(table.name, data.number_of_digits, data.number, data.prefix)
823
-
824
- const composedNumber = await RecordPlugin.composers.entity.record(
825
- new EntityData(
826
- 'record',
827
- context.registerExplicitId(numberRecord.table, numberRecord.$id),
828
- ObjectData.fromObjectValue(numberRecord, node),
829
- node
830
- ),
831
- context
832
- )
833
-
834
- entities.push(composedNumber)
835
-
836
- composeData['number_ref'] = composedNumber.guid
837
- }
838
-
839
- documentation.forEach((doc) => {
840
- entities.push({
841
- kind: 'sys_documentation',
842
- node: node,
843
- data: doc,
844
- guid: doc.$id as string,
845
- })
846
- })
847
-
848
- const docs = composeDocumentation('', table.name, table.label)
849
- docs.forEach((doc) => {
850
- entities.push({
851
- kind: 'sys_documentation',
852
- node: node,
853
- data: doc,
854
- guid: doc.$id as string,
855
- })
856
- })
857
-
858
- composeData['index'] = table.index
859
-
860
- if (table.licensing_config) {
861
- entities.push(composeLicenseConfig(composeData.name, table.licensing_config, node))
862
- }
863
-
864
- entities.push({
865
- kind: 'bootstrap',
866
- node,
867
- guid: composeData.name,
868
- data: { data: { bootstrapData: composeData, dbObjectData: composeData } },
869
- })
870
-
871
- return entities
872
- },
873
- },
874
- xml: {
875
- bootstrap(xml) {
876
- return {
877
- kind: xml.kind,
878
- guid: xml.data['name'] as string,
879
- data: { data: { bootstrapData: xml.data } },
880
- }
881
- },
882
- sys_db_object(xml) {
883
- return {
884
- kind: 'bootstrap',
885
- guid: `${xml.data['name']}`,
886
- data: { data: { dbObjectData: xml.data } },
887
- action: xml.action,
888
- }
889
- },
890
- sys_dictionary(xml) {
891
- const data = xml.data['data']!
892
- return {
893
- kind: 'sys_dictionary',
894
- guid:
895
- (xml.data['id'] as string) ??
896
- `${data['name']}_${data['element'] !== '' ? data['element'] : '_null'}`,
897
- data: xml.data,
898
- action: xml.action,
899
- }
900
- },
901
- },
902
- },
903
- arrangers: {
904
- bootstrap(_document: Document<any>) {
905
- return { handled: false }
906
- },
907
- sys_dictionary(document: Document<any>) {
908
- if ((document.data as any).table !== 'sys_dictionary') {
909
- return { handled: false }
910
- }
911
- const tableName = (document.data as any).data.name
912
- return {
913
- handled: true,
914
- result: tableName ? { kind: 'bootstrap', guid: tableName } : undefined,
915
- }
916
- },
917
- },
918
- generators: {
919
- bootstrap(document, context) {
920
- const parsedBoostrapData = TableSchemaBootstrapIncoming.safeParse(
921
- (document.data as ComposedTableData).data.bootstrapData
922
- )
923
- if (!parsedBoostrapData.success) {
924
- return undefined
925
- }
926
-
927
- return linkDocument(
928
- document,
929
- generateNamedCallExpressionExportForDocument(
930
- context,
931
- {
932
- sourceFile: getOrCreateEntitySourceFile(context, parsedBoostrapData.data.name),
933
- moduleSpecifier: '@servicenow/sdk/core',
934
- exportName: parsedBoostrapData.data.name,
935
- },
936
- Table,
937
- {}
938
- ).getInitializerIfKindOrThrow(ts.SyntaxKind.CallExpression)
939
- )
940
- },
941
- sys_dictionary(document, context: Context, linkedDocuments) {
942
- const data = (document.data as any).data
943
- const updateName = data.sys_update_name
944
- const table = linkedDocuments.find((doc) => doc.guid === data.name)
945
- return table && table.node
946
- ? { ...document, node: table.node }
947
- : linkDocument(
948
- document,
949
- generateCallExpressionExportForDocument(
950
- context,
951
- {
952
- sourceFile: getOrCreateEntitySourceFile(
953
- context,
954
- updateName ?? `sys_dictionary_${document.guid}`
955
- ),
956
- moduleSpecifier: '@servicenow/sdk/core',
957
- },
958
- NowRecord,
959
- { $id: document.guid }
960
- ).getExpressionIfKindOrThrow(ts.SyntaxKind.CallExpression)
961
- )
962
- },
963
- record(document, context) {
964
- if (
965
- document.data?.['table'] !== 'sys_documentation' &&
966
- document.data?.['table'] !== 'ua_table_licensing_config'
967
- ) {
968
- return
969
- }
970
-
971
- return linkDocument(
972
- document,
973
- generateCallExpression(
974
- context,
975
- getOrCreateEntitySourceFile(context, `${document.data?.['data'].name}`),
976
- '@servicenow/sdk/core',
977
- NowRecord,
978
- { $id: document.guid }
979
- )
980
- )
981
- },
982
- },
983
- serializers: {
984
- bootstrap(document) {
985
- const composedData = (document.data as ComposedTableData).data
986
- const { columns, index, attributes, ...bootstrapData } = composedData.bootstrapData
987
-
988
- if (bootstrapData.live_feed) {
989
- // live_feed needs to be a table sys_dictionary attribute so it can be synced to sys_db_object by a startup process
990
- attributes['live_feed'] = true
991
- }
992
-
993
- const root = create({ version: '1.0' }).ele('database')
994
- const composedAttributes = composeAttributes(attributes)
995
- const collection = root.ele('element', { ...bootstrapData, attributes: composedAttributes }!)
996
- for (const column of Object.values(columns)) {
997
- const { choice_elements, attributes, ...parsedColumn } = column as ColumnSchema
998
- const columnAttributes = composeAttributes(attributes)
999
- const element = collection.ele('element', { ...parsedColumn, attributes: columnAttributes }!)
1000
-
1001
- buildChoices(column as ColumnSchema, element)
1002
- }
1003
-
1004
- buildIndexes(index, collection)
1005
-
1006
- return {
1007
- name: `${bootstrapData.name}.xml`,
1008
- directory: 'dictionary',
1009
- content: root.end({ prettyPrint: true }),
1010
- usedIds: [],
1011
- }
1012
- },
1013
- sys_dictionary(_document) {
1014
- // Don't serialize
1015
- return undefined
1016
- },
1017
- },
1018
- transformers: {
1019
- bootstrap: {
1020
- CallExpression(document, context) {
1021
- return transformTable(document, context)
1022
- },
1023
- },
1024
- sys_dictionary: {
1025
- CallExpression(document, context: Context) {
1026
- if (getCallExpressionName(document.node as ts.CallExpression) !== Table.name) {
1027
- return RecordPlugin.transformers!.record!.CallExpression(document, context)
1028
- }
1029
-
1030
- context.logger.info(
1031
- `Deferring handling of sys_dictionary '${document.guid}' values to values in bootstrap.xml '${document.parent!.guid}'`
1032
- )
1033
- return true
1034
- },
1035
- },
1036
- },
1037
- postProcessors: {
1038
- entities(entities, context) {
1039
- const { interfaces, properties, imports, namedImports } = {
1040
- interfaces: [] as ts.OptionalKind<ts.InterfaceDeclarationStructure>[],
1041
- properties: [] as ts.OptionalKind<ts.PropertySignatureStructure>[],
1042
- imports: {} as Record<string, ts.OptionalKind<ts.ImportDeclarationStructure>>,
1043
- namedImports: [] as (ts.OptionalKind<ts.ImportSpecifierStructure> & {
1044
- existingImport: ts.ImportDeclaration
1045
- })[],
1046
- }
1047
- const generatedTableFile: ts.SourceFile | undefined = context.compiler.getGeneratedTableFile()
1048
- entities
1049
- .filter((entity) => entity.getKind() === 'table')
1050
- .forEach((table) => {
1051
- const tableName = table.getProperty('name')!.getValue() as string
1052
- const extendsTable = table.getProperty('extends')?.getValue() as string
1053
- if (tableName && tableName.trim().length > 0 && tableName.match(tableNameRegex)) {
1054
- if (!context.compiler.interfaceExistsInGlobalDeclaration(tableName)) {
1055
- interfaces.push({
1056
- name: tableName,
1057
- extends: [`Helper<typeof ${tableName}>`],
1058
- })
1059
- }
1060
- if (!context.compiler.propertyExistsInGlobalDeclaration(tableName)) {
1061
- let interfaceType = `Table<TableSchemas.${tableName}>`
1062
- if (extendsTable) {
1063
- interfaceType = `Table<TableSchemas.${tableName}, "${extendsTable}">`
1064
- }
1065
- properties.push({
1066
- name: tableName,
1067
- type: interfaceType,
1068
- })
1069
- }
1070
-
1071
- const filePath = table.getNode().getSourceFile().getFilePath()
1072
- const resolvedModuleSpecifier = generatedTableFile?.getRelativePathAsModuleSpecifierTo(
1073
- filePath
1074
- ) as string
1075
- const importExists = context.compiler.importExistsInGlobalDeclaration(resolvedModuleSpecifier)
1076
-
1077
- if (!importExists) {
1078
- if (imports[filePath]) {
1079
- ;(imports[filePath].namedImports! as string[]).push(tableName)
1080
- } else {
1081
- imports[filePath] = {
1082
- namedImports: [tableName],
1083
- moduleSpecifier: resolvedModuleSpecifier,
1084
- }
1085
- }
1086
- } else {
1087
- const namedImportExists = importExists
1088
- ?.getNamedImports()
1089
- .find((value) => value.getName() === tableName)
1090
- if (!namedImportExists) {
1091
- namedImports.push({
1092
- existingImport: importExists,
1093
- name: tableName,
1094
- })
1095
- }
1096
- }
1097
- }
1098
- })
1099
- context.compiler.addTableInterfacesToGlobalDeclaration({
1100
- interfaces,
1101
- properties,
1102
- imports,
1103
- namedImports,
1104
- })
1105
- },
1106
- },
1107
- })
1108
-
1109
- function transformTable(document, context) {
1110
- const expressionName = getCallExpressionName(document.node)
1111
- if (expressionName !== Table.name) {
1112
- return false
1113
- }
1114
- const [args] = document.node.getArguments()
1115
- if (!ts.Node.isObjectLiteralExpression(args)) {
1116
- return false
1117
- }
1118
-
1119
- if (document.action === 'DELETE') {
1120
- removeNode(document.node)
1121
- return true
1122
- }
1123
-
1124
- if (!document.changedData) {
1125
- return true
1126
- }
1127
-
1128
- const composedData = (document.changedData as ComposedTableData).data
1129
- const xmlData = (document.xmlData as ComposedTableData).data
1130
-
1131
- let bootstrap_data = {}
1132
- let db_data = {}
1133
- if (!isEmpty(composedData.bootstrapData)) {
1134
- // sys_db_object or node without bootstrap.xml. Mark as handled and ignore
1135
- bootstrap_data = TableSchemaBootstrapIncoming.partial().parse(composedData.bootstrapData)
1136
- }
1137
- if (!isEmpty(composedData.dbObjectData)) {
1138
- db_data = DBObjectIncomingAttributes.partial().parse(composedData.dbObjectData)
1139
- }
1140
-
1141
- const { auto_number, number_ref, extends: ext, index, columns, ...bootstrap_rest } = mapNames(bootstrap_data)
1142
- const { create_access, delete_access, update_access, read_access, caller_access, ...db_rest } = mapNames(db_data)
1143
- const rest = { ...bootstrap_rest, ...db_rest }
1144
-
1145
- if (ext) {
1146
- rest['extends'] = ext
1147
- }
1148
-
1149
- if (caller_access) {
1150
- rest['caller_access'] = callerAccess[caller_access]
1151
- }
1152
-
1153
- if (!isEmpty(db_data)) {
1154
- rest.actions = getActionsArray(xmlData.dbObjectData)
1155
- }
1156
-
1157
- if (!rest.attributes) {
1158
- delete rest.attributes
1159
- }
1160
-
1161
- transformFunctionArguments(document.node, Table as any, rest)
1162
-
1163
- // Handle columns
1164
- const incomingColumns = xmlData.bootstrapData ? xmlData.bootstrapData.columns : undefined
1165
-
1166
- updateDisplayValue(document.node, columns, incomingColumns)
1167
- transformColumns(columns, incomingColumns, args, context)
1168
- transformIndexes(xmlData, args)
1169
- return true
1170
- }
1171
-
1172
- function transformIndexes(xmlData, args) {
1173
- if (xmlData.bootstrapData?.index?.length > 0) {
1174
- // find the correct object literal
1175
- const indexProp = getPropertyAssignment(args, 'index')
1176
- if (indexProp) {
1177
- mergeDataIntoObjectLiteralArray(
1178
- indexProp.getFirstChildByKindOrThrow(ts.SyntaxKind.ArrayLiteralExpression),
1179
- Object.values(xmlData.bootstrapData?.index),
1180
- 'name'
1181
- )
1182
- } else {
1183
- const newIndexProp = getOrCreatePropertyAssignment(args, 'index', '[]')
1184
- newIndexProp.setInitializer(stringify(xmlData.bootstrapData.index))
1185
- }
1186
- } else if (xmlData.bootstrapData) {
1187
- const indexProp = getPropertyAssignment(args, 'index')
1188
- if (indexProp) {
1189
- indexProp.remove()
1190
- }
1191
- }
1192
- }
1193
-
1194
- function composeAttributes(attributes: Record<string, any> | undefined) {
1195
- if (!attributes) {
1196
- return ''
1197
- }
1198
-
1199
- return Object.entries(attributes)
1200
- .map(([key, value]) => `${key}=${value}`)
1201
- .join(',')
1202
- }
1203
-
1204
- function updateDisplayValue(node: ts.CallExpression, columns: ColumnSchema, incomingColumns: ColumnSchema) {
1205
- const display = Object.values(columns ?? {}).filter((col: any) => col.display)
1206
- if (display) {
1207
- const displayName = Object.values(incomingColumns ?? {}).find((c) => c.display)
1208
- if (displayName) {
1209
- transformFunctionArguments(node, Table as any, { display: displayName.name })
1210
- }
1211
- }
1212
- }
1213
-
1214
- function composeDocumentation(columnName: string, tableName: string, labels?: string | Documentation[]): NowRecord[] {
1215
- const labelData: NowRecord[] = []
1216
-
1217
- if (!labels || !isArray(labels)) {
1218
- return labelData
1219
- }
1220
-
1221
- labels.forEach((label) => {
1222
- const labelValue = label.label ?? columnName !== '' ? columnName : tableName
1223
- labelData.push(
1224
- NowRecord({
1225
- table: 'sys_documentation',
1226
- $id: `${tableName}_${columnName ? columnName + '_' : ''}${label.language}`,
1227
- data: { label: labelValue, element: columnName, name: tableName, ...label },
1228
- })
1229
- )
1230
- })
1231
- return labelData
1232
- }
1233
-
1234
- function getLabel(label?: string | Documentation[]): string | undefined {
1235
- if (!label || isArray(label)) {
1236
- // use column name if no label specified
1237
- return
1238
- }
1239
-
1240
- // label is an explicit string value
1241
- return label
1242
- }
1243
-
1244
- export function getDefaultMaxLength(column: ColumnSchema): number {
1245
- switch (column.entityKind) {
1246
- case 'conditions':
1247
- case 'glide_list':
1248
- return 4000
1249
- case 'decimal':
1250
- return 20
1251
- case 'domain_id':
1252
- case 'document_id':
1253
- case 'reference':
1254
- return 32
1255
- case 'domain_path':
1256
- case 'user_roles':
1257
- return 255
1258
- case 'script':
1259
- return 8000
1260
- case 'table_name':
1261
- case 'field_name':
1262
- return 80
1263
- default:
1264
- /**
1265
- * For types mentioned below it default to 40 on instance
1266
- * boolean | integer | image | choice | radio | sys_class_name | translated_field | translated_text | version | glide_date | glide_date_time | calendar_date_time
1267
- * datetime | due_date | integer_date | schedule_date_time | date | generic
1268
- *
1269
- * TODO::We need to request max_length from user for string column type because its mandatory on instance.
1270
- */
1271
- return 40
1272
- }
1273
- }
1274
-
1275
- function composeColumns(columns: Record<string, ColumnSchema>, _context: Context, tableName: string, display?: string) {
1276
- const composedColumns = {}
1277
- const documentation: NowRecord[] = []
1278
- for (const [columnName, columnData] of Object.entries(columns)) {
1279
- const { maxLength, ...rest } = columnData
1280
- const column = ColumnSchema.parse(rest)
1281
- const requiresDropdown = column.dynamic_value_definitions || column.choices
1282
- const element = {
1283
- name: columnName,
1284
- type: column.entityKind === 'generic' ? column.column_type : column.entityKind,
1285
- attributes: column.attributes ?? undefined,
1286
- reference: column.referenceTable,
1287
- reference_cascade_rule: column.referenceTable ? column.cascadeRule : undefined,
1288
- audit: column.audit,
1289
- label: getLabel(column.label) ?? columnName,
1290
- max_length: maxLength ?? getDefaultMaxLength(column),
1291
- mandatory: column.mandatory,
1292
- read_only: column.read_only,
1293
- choice: choiceDropdown.indexOf(column.dropdown ?? (requiresDropdown ? 'dropdown_with_none' : 'none')),
1294
- display: display ? display === columnName : false,
1295
-
1296
- // dynamic values
1297
- virtual: column.dynamic_value_definitions?.type === 'calculated_value' ? true : undefined,
1298
- calculation:
1299
- column.dynamic_value_definitions?.type === 'calculated_value'
1300
- ? typeof column.dynamic_value_definitions!['calculated_value'] === 'string'
1301
- ? column.dynamic_value_definitions!['calculated_value']
1302
- : ModuleFunctionData.getGlueCode(
1303
- column.dynamic_value_definitions!['calculated_value'],
1304
- (n) => `${n}(current)`
1305
- )
1306
- : undefined,
1307
- choice_table:
1308
- column.dynamic_value_definitions?.type === 'choices_from_other_table'
1309
- ? column.dynamic_value_definitions.table
1310
- : undefined,
1311
- choice_field:
1312
- column.dynamic_value_definitions?.type === 'choices_from_other_table'
1313
- ? column.dynamic_value_definitions.field
1314
- : undefined,
1315
-
1316
- use_dependent_field: column.dynamic_value_definitions?.type === 'dependent_field' || undefined,
1317
-
1318
- dependent:
1319
- column.dynamic_value_definitions?.type === 'dependent_field'
1320
- ? column.dynamic_value_definitions!['column_name']
1321
- : undefined,
1322
-
1323
- default: column.default,
1324
-
1325
- function_definition: column.function_definition,
1326
- function_field: column.function_definition ? true : false,
1327
-
1328
- plural: column.plural,
1329
- hint: column.hint,
1330
- help: column.help,
1331
- widget: column.widget,
1332
- table_reference: column.table_reference,
1333
- element_reference: column.element_reference,
1334
- reference_key: column.reference_key,
1335
- spell_check: column.spell_check,
1336
- xml_view: column.xml_view,
1337
- reference_floats: column.reference_floats,
1338
- dynamic_creation: column.dynamic_creation,
1339
- dynamic_creation_script: column.dynamic_creation_script,
1340
- array: column.array,
1341
- text_index: column.text_index,
1342
- primary: column.primary,
1343
- unique: column.unique,
1344
- reference_qual: column.reference_qual,
1345
- }
1346
-
1347
- documentation.push(...composeDocumentation(columnName, tableName, column.label))
1348
-
1349
- if (column.choices) {
1350
- Object.keys(column.choices).forEach((key) => {
1351
- if (isObject(column.choices![key])) {
1352
- column.choices![key] = { value: key, ...column.choices![key] }
1353
- } else {
1354
- column.choices![key] = { value: key, label: column.choices![key] }
1355
- }
1356
- })
1357
- element['choice_elements'] = z.record(ChoiceSchema).parse(column.choices)
1358
- }
1359
-
1360
- composedColumns[columnName] = element
1361
- }
1362
- return { columnData: composedColumns, documentation }
1363
- }
1364
-
1365
- function compose(bootstrapData: z.infer<typeof TableSchemaBootstrap>) {
1366
- if (bootstrapData.live_feed) {
1367
- bootstrapData.attributes = {
1368
- // live_feed needs to be a table sys_dictionary attribute so it can be synced to sys_db_object by a startup process
1369
- ...bootstrapData.attributes,
1370
- live_feed: true,
1371
- }
1372
- }
1373
-
1374
- const composedData = {
1375
- // Generic data
1376
- name: bootstrapData.name,
1377
- type: 'collection',
1378
- extends: bootstrapData.extends,
1379
- label: getLabel(bootstrapData.label) ?? bootstrapData.name,
1380
-
1381
- // Controls
1382
- is_extendable: bootstrapData.extensible,
1383
- text_index: bootstrapData.text_index,
1384
- read_only: bootstrapData.read_only,
1385
- audit: bootstrapData.audit,
1386
-
1387
- access: bootstrapData.accessible_from,
1388
- caller_access: callerAccess.indexOf(bootstrapData.caller_access ?? 'none'),
1389
-
1390
- read_access: bootstrapData.actions?.includes('read'),
1391
- update_access: bootstrapData.actions?.includes('update'),
1392
- create_access: bootstrapData.actions?.includes('create'),
1393
- delete_access: bootstrapData.actions?.includes('delete'),
1394
-
1395
- ws_access: bootstrapData.allow_web_service_access,
1396
- alter_access: bootstrapData.allow_new_fields,
1397
- actions_access: bootstrapData.allow_ui_actions,
1398
- client_scripts_access: bootstrapData.allow_client_scripts,
1399
-
1400
- scriptable_table: bootstrapData.scriptable_table,
1401
-
1402
- attributes: bootstrapData.attributes,
1403
- }
1404
-
1405
- return composedData
1406
- }
1407
-
1408
- // API properties that are different in the bootstrap/sys_db_object file
1409
- const property_name_mapping = {
1410
- client_scripts_access: 'allow_client_scripts',
1411
- alter_access: 'allow_new_fields',
1412
- actions_access: 'allow_ui_actions',
1413
- ws_access: 'allow_web_service_access',
1414
- is_extendable: 'extensible',
1415
- access: 'accessible_from',
1416
- live_feed_enabled: 'live_feed',
1417
- }
1418
-
1419
- function mapNames(schema: any) {
1420
- Object.keys(schema).forEach((key) => {
1421
- if (property_name_mapping[key]) {
1422
- schema[property_name_mapping[key]] = schema[key]
1423
- delete schema[key]
1424
- }
1425
- })
1426
- return schema
1427
- }
1428
-
1429
- function transformColumns(
1430
- columns: ColumnSchema,
1431
- incomingSchema: ColumnSchema,
1432
- args: ts.ObjectLiteralExpression,
1433
- context: Context
1434
- ) {
1435
- const schemaProperty = getOrCreatePropertyAssignment(args, 'schema', '{}')
1436
-
1437
- if (!incomingSchema) {
1438
- return
1439
- }
1440
-
1441
- const schemaLiteral = schemaProperty.getChildrenOfKind(ts.SyntaxKind.ObjectLiteralExpression)[0]
1442
- if (!schemaLiteral) {
1443
- return
1444
- }
1445
-
1446
- const existingColumns = {}
1447
- schemaLiteral.getProperties().forEach((property) => {
1448
- const propertyAssignment = property.asKindOrThrow(ts.SyntaxKind.PropertyAssignment)
1449
- const name = propertyAssignment.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier).getText()
1450
- const callExp = propertyAssignment.getFirstChildByKindOrThrow(ts.SyntaxKind.CallExpression)
1451
- const callExpType = callExp.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier).getText()
1452
- const objectLiteral = callExp.getFirstChildByKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression)
1453
- existingColumns[name] = {
1454
- node: propertyAssignment,
1455
- type: callExpType,
1456
- objectLiteral,
1457
- }
1458
-
1459
- if (!incomingSchema[name]) {
1460
- // Full bootstrap.xml does not have this existing column so remove it
1461
- removeNode(propertyAssignment)
1462
- }
1463
- })
1464
-
1465
- if (!columns || isEmpty(columns)) {
1466
- return
1467
- }
1468
-
1469
- Object.keys(incomingSchema).forEach((key) => {
1470
- const partialData = columns[key]
1471
- if (!existingColumns[key]) {
1472
- // This column doesn't exist so let's make it
1473
- const callExpFromType = getCallExpressionFromType(partialData.type)
1474
- createNewColumn(schemaLiteral, callExpFromType.name, partialData, context)
1475
- } else {
1476
- const existingColumn = existingColumns[key]
1477
- if (partialData) {
1478
- if (partialData.type && existingColumn.type !== partialData.type) {
1479
- // Switching the column type so regenerate the CallExpression and add all incoming data
1480
- removeNode(existingColumn.node)
1481
- const callExpFromType = getCallExpressionFromType(partialData.type)
1482
- createNewColumn(schemaLiteral, callExpFromType.name, incomingSchema[key], context)
1483
- } else {
1484
- // Update the existing column with changed data only
1485
- const transformedColumnData = transformColumnData(partialData, existingColumn.type)
1486
- mergeDataIntoObjectLiteral(existingColumn.objectLiteral, {
1487
- ...transformedColumnData,
1488
- choices: partialData.choice_elements,
1489
- })
1490
- }
1491
- }
1492
- if (existingColumn.node && !existingColumn.node.wasForgotten()) {
1493
- removeChoicesIfNecessary(existingColumn, incomingSchema[key])
1494
- removeAttributesIfNecessary(existingColumn, incomingSchema[key])
1495
- }
1496
- }
1497
- })
1498
- }
1499
-
1500
- function removeChoicesIfNecessary(existingColumn: any, columnFromBootstrap: any) {
1501
- const existingProperties = existingColumn.objectLiteral
1502
- .getProperties()
1503
- .reduce((a, v) => ({ ...a, [getObjectPropertyAssignmentName(v)]: v }), {})
1504
-
1505
- if (!existingProperties['choices']) {
1506
- return
1507
- }
1508
-
1509
- if (!columnFromBootstrap['choice_elements']) {
1510
- removeNode(existingProperties['choices'])
1511
- return
1512
- }
1513
-
1514
- const choicesFromBootstrap = Object.keys(columnFromBootstrap['choice_elements'])
1515
- const existingChoices = existingProperties['choices']
1516
- .getFirstChildByKind(ts.SyntaxKind.ObjectLiteralExpression)
1517
- .getProperties()
1518
- .reduce((a, v) => {
1519
- return {
1520
- ...a,
1521
- [getObjectPropertyAssignmentName(v)]: v,
1522
- }
1523
- }, {})
1524
- Object.keys(existingChoices).forEach((choice) => {
1525
- if (!choicesFromBootstrap.includes(choice)) {
1526
- removeNode(existingChoices[choice])
1527
- }
1528
- })
1529
- }
1530
-
1531
- function removeAttributesIfNecessary(existingColumn: any, columnFromBootstrap: any) {
1532
- const existingProperties = existingColumn.objectLiteral
1533
- .getProperties()
1534
- .reduce((a, v) => ({ ...a, [getObjectPropertyAssignmentName(v)]: v }), {})
1535
-
1536
- if (!existingProperties['attributes']) {
1537
- return
1538
- }
1539
-
1540
- if (!columnFromBootstrap['attributes']) {
1541
- removeNode(existingProperties['attributes'])
1542
- return
1543
- }
1544
-
1545
- const existingAttributes = existingProperties['attributes']
1546
- .getFirstChildByKind(ts.SyntaxKind.ObjectLiteralExpression)
1547
- .getProperties()
1548
- .reduce((a, v) => ({ ...a, [getObjectPropertyAssignmentName(v)]: v }), {})
1549
- Object.keys(existingAttributes).forEach((attr) => {
1550
- if (!(attr in columnFromBootstrap['attributes'])) {
1551
- removeNode(existingAttributes[attr])
1552
- }
1553
- })
1554
- }
1555
-
1556
- function generateNamedCallExpressionExportForDocument<const A extends unknown[]>(
1557
- context: Context,
1558
- info: {
1559
- sourceFile: ts.SourceFile
1560
- moduleSpecifier: string
1561
- exportName: string
1562
- },
1563
- fn: (...args: A) => unknown,
1564
- ...args: PartialElements<A>
1565
- ) {
1566
- const { sourceFile, moduleSpecifier } = info
1567
- return generateCallExpressionExport(context, sourceFile, moduleSpecifier, info.exportName, fn, ...args)
1568
- }
1569
-
1570
- function createNewColumn(schemaLiteral: ts.ObjectLiteralExpression, callExpName: string, data: any, context: Context) {
1571
- const propertyAssignment = schemaLiteral.addPropertyAssignment({
1572
- name: data.name,
1573
- initializer: `${callExpName}({})`,
1574
- })
1575
- const objectLiteral = propertyAssignment
1576
- .getInitializer()!
1577
- .getFirstChildByKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression)
1578
- const transformedColumnData = transformColumnData(data, callExpName)
1579
- mergeDataIntoObjectLiteral(objectLiteral, { ...transformedColumnData, choices: data.choice_elements })
1580
- addNamedImportIfAbsent(context, schemaLiteral.getSourceFile(), '@servicenow/sdk/core', {
1581
- name: callExpName,
1582
- })
1583
- }
1584
-
1585
- type DB_ACTIONS = 'read' | 'delete' | 'create' | 'update'
1586
-
1587
- function getActionsArray(data) {
1588
- const actions: DB_ACTIONS[] = []
1589
- if (data.read_access) {
1590
- actions.push('read')
1591
- }
1592
- if (data.update_access) {
1593
- actions.push('update')
1594
- }
1595
- if (data.delete_access) {
1596
- actions.push('delete')
1597
- }
1598
- if (data.create_access) {
1599
- actions.push('create')
1600
- }
1601
-
1602
- return actions
1603
- }
1604
-
1605
- function buildIndexes(indexes: IndexType[] = [], collection: XMLBuilder) {
1606
- indexes.forEach((index) => {
1607
- const indexElement = collection.ele('index', { name: index.name, unique: index.unique })
1608
- if (isArray(index.element)) {
1609
- index.element.forEach((element) => {
1610
- indexElement.ele('element', { name: element })
1611
- })
1612
- } else {
1613
- indexElement.ele('element', { name: index.element })
1614
- }
1615
- })
1616
- }
1617
-
1618
- function buildChoices(column: ColumnSchema, element: XMLBuilder) {
1619
- if (!column.choice_elements) {
1620
- return
1621
- }
1622
-
1623
- const choices = element.ele('choice')
1624
- if (Array.isArray(column.choices) && column.choices.length > 0) {
1625
- // Formatted - choices: [1, 2, 3, 4]
1626
- for (const choice in column.choices) {
1627
- choices.ele('element', {
1628
- value: column.choices[choice],
1629
- label: column.choices[choice],
1630
- })
1631
- }
1632
- } else {
1633
- // Formatted - choices: { 1: { label: 'label' }, 2: { lable: label 2}, ...}
1634
- Object.entries(column.choice_elements).forEach((value) => {
1635
- if (isObject(value[1])) {
1636
- choices.ele('element', {
1637
- value: value[0],
1638
- ...(value[1] as ChoiceConfig),
1639
- })
1640
- } else {
1641
- choices.ele('element', {
1642
- value: value[1],
1643
- label: value[0],
1644
- })
1645
- }
1646
- })
1647
- }
1648
- }
1649
-
1650
- function transformColumnData(col: any, callExpFromType: string) {
1651
- const {
1652
- type: internal_type,
1653
- choice,
1654
- name,
1655
- virtual,
1656
- display,
1657
- choice_table,
1658
- choice_field,
1659
- use_dependent_field,
1660
- dependent,
1661
- calculation,
1662
- use_dynamic_default,
1663
- default_value,
1664
- choice_elements,
1665
- table,
1666
- default: def,
1667
- max_length,
1668
- reference,
1669
- reference_cascade_rule,
1670
- function_field,
1671
- reference_qual_condition,
1672
- ...column
1673
- } = col
1674
-
1675
- if (max_length !== undefined) {
1676
- column.maxLength = parseInt(max_length, 10)
1677
- }
1678
-
1679
- if (internal_type && callExpFromType === 'GenericColumn') {
1680
- column.column_type = internal_type
1681
- }
1682
-
1683
- if (choice !== undefined) {
1684
- column.dropdown = choiceDropdown[choice]
1685
- }
1686
-
1687
- if (reference) {
1688
- column.referenceTable = reference
1689
- }
1690
- if (reference_cascade_rule) {
1691
- column.cascadeRule = reference_cascade_rule
1692
- }
1693
-
1694
- // Handle dynamic values
1695
- if (calculation) {
1696
- column.dynamic_value_definitions = {
1697
- type: 'calculated_value',
1698
- calculated_value: calculation,
1699
- }
1700
- } else if (choice_table || choice_field) {
1701
- column.dynamic_value_definitions = {
1702
- type: 'choices_from_other_table',
1703
- table: choice_table,
1704
- field: choice_field,
1705
- }
1706
- } else if (dependent) {
1707
- column.dynamic_value_definitions = {
1708
- type: 'dependent_field',
1709
- column_name: dependent,
1710
- }
1711
- } else if (def) {
1712
- column.default = def
1713
- } else if (default_value) {
1714
- column.default = default_value
1715
- }
1716
-
1717
- if (column.label && column.label === name) {
1718
- delete column.label
1719
- }
1720
-
1721
- if (isEmpty(column.attributes)) {
1722
- delete column.attributes
1723
- } else if (isDefaultEdgeEncryptionAttribute(column.attributes)) {
1724
- delete column.attributes
1725
- }
1726
-
1727
- return column
1728
- }
1729
-
1730
- // The instance will sometimes add edge_encryption_enabled=true, this is a default so don't write it if it is the only one
1731
- function isDefaultEdgeEncryptionAttribute(attributes: any) {
1732
- return (
1733
- attributes &&
1734
- Object.entries(attributes).length === 1 &&
1735
- attributes.edge_encryption_enabled !== undefined &&
1736
- attributes.edge_encryption_enabled
1737
- )
1738
- }
1739
-
1740
- function removeAttributeTag(obj: any) {
1741
- Object.entries(obj).forEach(([key, value]) => {
1742
- if (key.startsWith('@_')) {
1743
- obj[key.substring(2)] = value
1744
- delete obj[key]
1745
- }
1746
- })
1747
- return obj
1748
- }
1749
-
1750
- function SysNumber(
1751
- category: TableName,
1752
- maximum_digits: number | undefined,
1753
- number?: number | undefined,
1754
- prefix?: string | undefined
1755
- ) {
1756
- return NowRecord({
1757
- table: 'sys_number',
1758
- $id: `${category as string}_${prefix}`,
1759
- data: {
1760
- category,
1761
- maximum_digits: maximum_digits ?? 1000,
1762
- number: number ?? 7,
1763
- prefix: prefix ?? 'PRE',
1764
- },
1765
- })
1766
- }
1767
-
1768
- export function generateColumnExpression<Type extends (...args: any) => any>(
1769
- expression: Type,
1770
- args: Parameters<Type>[0],
1771
- argsSetIfDefined?: Undefined<Parameters<Type>[0]>
1772
- ): tsc.CallExpression {
1773
- const setArgs = { ...args }
1774
- if (argsSetIfDefined) {
1775
- Object.keys(argsSetIfDefined).forEach((key) => {
1776
- if (argsSetIfDefined[key] !== undefined) {
1777
- setArgs[key] = argsSetIfDefined[key]
1778
- }
1779
- })
1780
- }
1781
-
1782
- return tsc.factory.createCallExpression(tsc.factory.createIdentifier(expression.name), undefined, [
1783
- createObjectExpression(setArgs),
1784
- ])
1785
- }
1786
-
1787
- export function createObjectExpression(firstArg: object): tsc.Expression {
1788
- return tsc.factory.createObjectLiteralExpression(
1789
- Object.entries(firstArg)
1790
- .filter(([_key, value]) => value !== undefined)
1791
- .map(([key, value]) => {
1792
- if (key === 'referenceTable') {
1793
- return tsc.factory.createPropertyAssignment(
1794
- tsc.factory.createIdentifier('referenceTable'),
1795
- tsc.factory.createStringLiteral(value)
1796
- )
1797
- } else if (key === 'calculated_value') {
1798
- return tsc.factory.createPropertyAssignment(
1799
- tsc.factory.createIdentifier(key),
1800
- tsc.factory.createTaggedTemplateExpression(
1801
- tsc.factory.createIdentifier('script'),
1802
- undefined,
1803
- tsc.factory.createNoSubstitutionTemplateLiteral(value, value)
1804
- )
1805
- )
1806
- } else if (key === 'maxLength') {
1807
- if (isNaN(+value)) {
1808
- return tsc.factory.createPropertyAssignment(
1809
- tsc.factory.createIdentifier(key),
1810
- tsc.factory.createAsExpression(
1811
- tsc.factory.createStringLiteral(value),
1812
- tsc.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
1813
- )
1814
- )
1815
- }
1816
-
1817
- return tsc.factory.createPropertyAssignment(
1818
- tsc.factory.createIdentifier(key),
1819
- tsc.factory.createNumericLiteral(value)
1820
- )
1821
- }
1822
- return tsc.factory.createPropertyAssignment(
1823
- createPropertyIdentifier(key),
1824
- factoryCreateValue(value, tsc.factory)
1825
- )
1826
- })
1827
- )
1828
- }
1829
-
1830
- function factoryCreateValue(value: unknown, factory: tsc.NodeFactory) {
1831
- if (typeof value === 'string') {
1832
- return factory.createStringLiteral(value)
1833
- }
1834
-
1835
- if (typeof value === 'number') {
1836
- if (value >= 0) {
1837
- return factory.createNumericLiteral(value)
1838
- } else {
1839
- return factory.createPrefixUnaryExpression(
1840
- tsc.SyntaxKind.MinusToken,
1841
- factory.createNumericLiteral(Math.abs(value))
1842
- )
1843
- }
1844
- }
1845
-
1846
- if (typeof value === 'boolean') {
1847
- return value ? factory.createTrue() : factory.createFalse()
1848
- }
1849
-
1850
- if (typeof value === 'object') {
1851
- if (value === null) {
1852
- return factory.createNull()
1853
- }
1854
- if (isArray(value)) {
1855
- const newvals: tsc.Expression[] = []
1856
-
1857
- Object.values(value).forEach((v) => {
1858
- newvals.push(factoryCreateValue(v, factory))
1859
- })
1860
-
1861
- return factory.createArrayLiteralExpression(newvals)
1862
- } else if (ts.Structure.isImportSpecifier(value)) {
1863
- return factory.createIdentifier(value['name'])
1864
- } else {
1865
- return createObjectExpression(value)
1866
- }
1867
- }
1868
-
1869
- return factory.createNull()
1870
-
1871
- // throw new Error(`Unsupported value type: ${typeof value}`)
1872
- }
1873
-
1874
- type Undefined<T> = {
1875
- [P in keyof T]: T[P] | undefined
1876
- }
1877
- function getCallExpressionFromType(internal_type: string) {
1878
- switch (internal_type) {
1879
- case undefined:
1880
- case 'string':
1881
- return StringColumn
1882
- case 'boolean':
1883
- return BooleanColumn
1884
- case 'choice':
1885
- return ChoiceColumn
1886
- case 'conditions':
1887
- return ConditionsColumn
1888
- case 'date':
1889
- return OtherDateColumn
1890
- case 'calendar_date_time':
1891
- return CalendarDateTimeColumn
1892
- case 'datetime':
1893
- return BasicDateTimeColumn
1894
- case 'due_date':
1895
- return DueDateColumn
1896
- case 'glide_date':
1897
- return DateColumn
1898
- case 'glide_date_time':
1899
- return DateTimeColumn
1900
- case 'integer_date':
1901
- return IntegerDateColumn
1902
- case 'schedule_date_time':
1903
- return ScheduleDateTimeColumn
1904
- case 'decimal':
1905
- return DecimalColumn
1906
- case 'document_id':
1907
- return DocumentIdColumn
1908
- case 'domain_id':
1909
- return DomainIdColumn
1910
- case 'domain_path':
1911
- return DomainPathColumn
1912
- case 'field_name':
1913
- return FieldNameColumn
1914
- case 'integer':
1915
- return IntegerColumn
1916
- case 'radio':
1917
- return RadioColumn
1918
- case 'reference':
1919
- return ReferenceColumn
1920
- case 'script':
1921
- return ScriptColumn
1922
- case 'sys_class_name':
1923
- return SystemClassNameColumn
1924
- case 'table_name':
1925
- return TableNameColumn
1926
- case 'translated_field':
1927
- return TranslatedFieldColumn
1928
- case 'translated_text':
1929
- return TranslatedTextColumn
1930
- case 'user_roles':
1931
- return UserRolesColumn
1932
- case 'version':
1933
- return VersionColumn
1934
- case 'glide_list':
1935
- return ListColumn
1936
- case 'image':
1937
- return BasicImageColumn
1938
- case 'int':
1939
- case 'string_types':
1940
- case 'approval_rules':
1941
- case 'audio':
1942
- case 'auto_increment':
1943
- case 'auto_number':
1944
- case 'bootstrap_color':
1945
- case 'breakdown_element':
1946
- case 'catalog_preview':
1947
- case 'char':
1948
- case 'collection':
1949
- case 'color':
1950
- case 'color_display':
1951
- case 'composite_field':
1952
- case 'composite_name':
1953
- case 'compressed':
1954
- case 'condition_string':
1955
- case 'counter':
1956
- case 'css':
1957
- case 'currency':
1958
- case 'currency2':
1959
- case 'data_array':
1960
- case 'data_object':
1961
- case 'data_structure':
1962
- case 'days_of_week':
1963
- case 'day_of_week':
1964
- case 'documentation_field':
1965
- case 'dynamic_json':
1966
- case 'email':
1967
- case 'email_script':
1968
- case 'expression':
1969
- case 'external_names':
1970
- case 'field_list':
1971
- case 'file_attachment':
1972
- case 'float':
1973
- case 'formula':
1974
- case 'geo_point':
1975
- case 'glide_action_list':
1976
- case 'glide_duration':
1977
- case 'glide_precise_time':
1978
- case 'glide_time':
1979
- case 'glide_utc_time':
1980
- case 'glide_var':
1981
- case 'glyphicon':
1982
- case 'graphql_schema':
1983
- case 'GUID':
1984
- case 'html':
1985
- case 'html_script':
1986
- case 'html_template':
1987
- case 'icon':
1988
- case 'index_name':
1989
- case 'insert_timestamp':
1990
- case 'integer_time':
1991
- case 'internal_type':
1992
- case 'ip_addr':
1993
- case 'ip_address':
1994
- case 'journal':
1995
- case 'journal_input':
1996
- case 'journal_list':
1997
- case 'json':
1998
- case 'json_translations':
1999
- case 'language':
2000
- case 'long':
2001
- case 'longint':
2002
- case 'mask_code':
2003
- case 'metric_absolute':
2004
- case 'metric_counter':
2005
- case 'metric_derive':
2006
- case 'metric_gauge':
2007
- case 'mid_config':
2008
- case 'month_of_year':
2009
- case 'multi_small':
2010
- case 'multi_two_lines':
2011
- case 'name_values':
2012
- case 'nds_icon':
2013
- case 'nl_task_int1':
2014
- case 'order_index':
2015
- case 'password':
2016
- case 'password2':
2017
- case 'percent_complete':
2018
- case 'phone_number':
2019
- case 'phone_number_e164':
2020
- case 'ph_number':
2021
- case 'price':
2022
- case 'properties':
2023
- case 'records':
2024
- case 'reference_name':
2025
- case 'related_tags':
2026
- case 'reminder_field_name':
2027
- case 'repeat_count':
2028
- case 'repeat_type':
2029
- case 'replication_payload':
2030
- case 'schedule_interval_count':
2031
- case 'script_client':
2032
- case 'script_plain':
2033
- case 'script_server':
2034
- case 'short_field_name':
2035
- case 'short_table_name':
2036
- case 'simple_name_values':
2037
- case 'slushbucket':
2038
- case 'snapshot_template_value':
2039
- case 'source_id':
2040
- case 'source_name':
2041
- case 'source_table':
2042
- case 'string_boolean':
2043
- case 'string_full_utf8':
2044
- case 'structure':
2045
- case 'sysevent_name':
2046
- case 'sysrule_field_name':
2047
- case 'sys_class_path':
2048
- case 'template_value':
2049
- case 'time':
2050
- case 'timer':
2051
- case 'translated':
2052
- case 'translated_html':
2053
- case 'tree_code':
2054
- case 'tree_path':
2055
- case 'url':
2056
- case 'user_image':
2057
- case 'user_input':
2058
- case 'variables':
2059
- case 'variable_conditions':
2060
- case 'variable_template_value':
2061
- case 'video':
2062
- case 'week_of_month':
2063
- case 'wide_text':
2064
- case 'wiki_text':
2065
- case 'wms_job':
2066
- case 'workflow':
2067
- case 'workflow_conditions':
2068
- case 'xml':
2069
- default:
2070
- return GenericColumn
2071
- }
2072
- }