@servicenow/sdk-build-plugins 4.4.0 → 4.5.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 (287) hide show
  1. package/dist/acl-plugin.js +54 -4
  2. package/dist/acl-plugin.js.map +1 -1
  3. package/dist/applicability-plugin.js +2 -0
  4. package/dist/applicability-plugin.js.map +1 -1
  5. package/dist/application-menu-plugin.js +2 -0
  6. package/dist/application-menu-plugin.js.map +1 -1
  7. package/dist/arrow-function-plugin.d.ts +6 -1
  8. package/dist/arrow-function-plugin.js +105 -12
  9. package/dist/arrow-function-plugin.js.map +1 -1
  10. package/dist/atf/test-plugin.js +2 -0
  11. package/dist/atf/test-plugin.js.map +1 -1
  12. package/dist/basic-syntax-plugin.js +20 -0
  13. package/dist/basic-syntax-plugin.js.map +1 -1
  14. package/dist/call-expression-plugin.js +1 -0
  15. package/dist/call-expression-plugin.js.map +1 -1
  16. package/dist/claims-plugin.js +1 -0
  17. package/dist/claims-plugin.js.map +1 -1
  18. package/dist/client-script-plugin.js +1 -0
  19. package/dist/client-script-plugin.js.map +1 -1
  20. package/dist/column-plugin.js +1 -0
  21. package/dist/column-plugin.js.map +1 -1
  22. package/dist/cross-scope-privilege-plugin.js +1 -0
  23. package/dist/cross-scope-privilege-plugin.js.map +1 -1
  24. package/dist/dashboard/dashboard-plugin.js +2 -0
  25. package/dist/dashboard/dashboard-plugin.js.map +1 -1
  26. package/dist/data-plugin.js +1 -0
  27. package/dist/data-plugin.js.map +1 -1
  28. package/dist/email-notification-plugin.js +9 -13
  29. package/dist/email-notification-plugin.js.map +1 -1
  30. package/dist/flow/constants/flow-plugin-constants.d.ts +1 -1
  31. package/dist/flow/constants/flow-plugin-constants.js +1 -1
  32. package/dist/flow/constants/flow-plugin-constants.js.map +1 -1
  33. package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +82 -2
  34. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +48 -40
  35. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -1
  36. package/dist/flow/flow-logic/flow-logic-plugin.js +1 -0
  37. package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -1
  38. package/dist/flow/plugins/approval-rules-plugin.js +1 -0
  39. package/dist/flow/plugins/approval-rules-plugin.js.map +1 -1
  40. package/dist/flow/plugins/flow-action-definition-plugin.js +4 -2
  41. package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
  42. package/dist/flow/plugins/flow-data-pill-plugin.js +1 -0
  43. package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -1
  44. package/dist/flow/plugins/flow-definition-plugin.js +8 -3
  45. package/dist/flow/plugins/flow-definition-plugin.js.map +1 -1
  46. package/dist/flow/plugins/flow-diagnostics-plugin.js +1 -0
  47. package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -1
  48. package/dist/flow/plugins/flow-instance-plugin.js +68 -12
  49. package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
  50. package/dist/flow/plugins/flow-trigger-instance-plugin.js +1 -0
  51. package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -1
  52. package/dist/flow/plugins/inline-script-plugin.js +1 -0
  53. package/dist/flow/plugins/inline-script-plugin.js.map +1 -1
  54. package/dist/flow/plugins/step-definition-plugin.js +3 -2
  55. package/dist/flow/plugins/step-definition-plugin.js.map +1 -1
  56. package/dist/flow/plugins/step-instance-plugin.js +1 -0
  57. package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
  58. package/dist/flow/plugins/trigger-plugin.js +2 -0
  59. package/dist/flow/plugins/trigger-plugin.js.map +1 -1
  60. package/dist/flow/plugins/wfa-datapill-plugin.js +1 -0
  61. package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -1
  62. package/dist/flow/post-install.d.ts +2 -0
  63. package/dist/flow/post-install.js +58 -0
  64. package/dist/flow/post-install.js.map +1 -0
  65. package/dist/flow/utils/complex-objects.js +4 -2
  66. package/dist/flow/utils/complex-objects.js.map +1 -1
  67. package/dist/flow/utils/flow-constants.d.ts +24 -0
  68. package/dist/flow/utils/flow-constants.js +29 -2
  69. package/dist/flow/utils/flow-constants.js.map +1 -1
  70. package/dist/flow/utils/flow-to-xml.d.ts +3 -2
  71. package/dist/flow/utils/flow-to-xml.js +3 -4
  72. package/dist/flow/utils/flow-to-xml.js.map +1 -1
  73. package/dist/flow/utils/label-cache-processor.d.ts +5 -0
  74. package/dist/flow/utils/label-cache-processor.js +14 -2
  75. package/dist/flow/utils/label-cache-processor.js.map +1 -1
  76. package/dist/flow/utils/service-catalog.js +5 -1
  77. package/dist/flow/utils/service-catalog.js.map +1 -1
  78. package/dist/form-plugin.d.ts +2 -0
  79. package/dist/form-plugin.js +1134 -0
  80. package/dist/form-plugin.js.map +1 -0
  81. package/dist/html-import-plugin.js +1 -0
  82. package/dist/html-import-plugin.js.map +1 -1
  83. package/dist/import-sets-plugin.js +2 -0
  84. package/dist/import-sets-plugin.js.map +1 -1
  85. package/dist/index.d.ts +9 -0
  86. package/dist/index.js +13 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/instance-scan-plugin.d.ts +2 -0
  89. package/dist/instance-scan-plugin.js +298 -0
  90. package/dist/instance-scan-plugin.js.map +1 -0
  91. package/dist/json-plugin.js +1 -0
  92. package/dist/json-plugin.js.map +1 -1
  93. package/dist/list-plugin.js +1 -0
  94. package/dist/list-plugin.js.map +1 -1
  95. package/dist/now-attach-plugin.js +1 -0
  96. package/dist/now-attach-plugin.js.map +1 -1
  97. package/dist/now-config-plugin.js +659 -51
  98. package/dist/now-config-plugin.js.map +1 -1
  99. package/dist/now-id-plugin.js +1 -0
  100. package/dist/now-id-plugin.js.map +1 -1
  101. package/dist/now-include-plugin.js +1 -0
  102. package/dist/now-include-plugin.js.map +1 -1
  103. package/dist/now-ref-plugin.js +1 -0
  104. package/dist/now-ref-plugin.js.map +1 -1
  105. package/dist/now-unresolved-plugin.js +1 -0
  106. package/dist/now-unresolved-plugin.js.map +1 -1
  107. package/dist/package-json-plugin.js +1 -0
  108. package/dist/package-json-plugin.js.map +1 -1
  109. package/dist/property-plugin.js +3 -1
  110. package/dist/property-plugin.js.map +1 -1
  111. package/dist/record-plugin.d.ts +30 -0
  112. package/dist/record-plugin.js +37 -1
  113. package/dist/record-plugin.js.map +1 -1
  114. package/dist/repack/lint/Rules.d.ts +11 -2
  115. package/dist/repack/lint/Rules.js +160 -16
  116. package/dist/repack/lint/Rules.js.map +1 -1
  117. package/dist/repack/lint/index.d.ts +10 -5
  118. package/dist/repack/lint/index.js +76 -50
  119. package/dist/repack/lint/index.js.map +1 -1
  120. package/dist/rest-api-plugin.js +14 -0
  121. package/dist/rest-api-plugin.js.map +1 -1
  122. package/dist/role-plugin.js +1 -0
  123. package/dist/role-plugin.js.map +1 -1
  124. package/dist/schedule-script/index.d.ts +1 -0
  125. package/dist/schedule-script/index.js +18 -0
  126. package/dist/schedule-script/index.js.map +1 -0
  127. package/dist/schedule-script/scheduled-script-plugin.d.ts +2 -0
  128. package/dist/schedule-script/scheduled-script-plugin.js +551 -0
  129. package/dist/schedule-script/scheduled-script-plugin.js.map +1 -0
  130. package/dist/schedule-script/timeZoneConverter.d.ts +61 -0
  131. package/dist/schedule-script/timeZoneConverter.js +170 -0
  132. package/dist/schedule-script/timeZoneConverter.js.map +1 -0
  133. package/dist/script-action-plugin.js +2 -0
  134. package/dist/script-action-plugin.js.map +1 -1
  135. package/dist/script-include-plugin.js +2 -0
  136. package/dist/script-include-plugin.js.map +1 -1
  137. package/dist/server-module-plugin/index.js +13 -2
  138. package/dist/server-module-plugin/index.js.map +1 -1
  139. package/dist/service-catalog/catalog-clientscript-plugin.js +2 -0
  140. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -1
  141. package/dist/service-catalog/catalog-item-plugin.js +2 -0
  142. package/dist/service-catalog/catalog-item-plugin.js.map +1 -1
  143. package/dist/service-catalog/catalog-ui-policy-plugin.js +2 -0
  144. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -1
  145. package/dist/service-catalog/sc-record-producer-plugin.js +2 -0
  146. package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -1
  147. package/dist/service-catalog/service-catalog-diagnostics.d.ts +6 -0
  148. package/dist/service-catalog/service-catalog-diagnostics.js +20 -0
  149. package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -1
  150. package/dist/service-catalog/shape-to-record.js +7 -2
  151. package/dist/service-catalog/shape-to-record.js.map +1 -1
  152. package/dist/service-catalog/variable-set-plugin.js +2 -0
  153. package/dist/service-catalog/variable-set-plugin.js.map +1 -1
  154. package/dist/service-portal/angular-provider-plugin.js +2 -0
  155. package/dist/service-portal/angular-provider-plugin.js.map +1 -1
  156. package/dist/service-portal/dependency-plugin.js +5 -31
  157. package/dist/service-portal/dependency-plugin.js.map +1 -1
  158. package/dist/service-portal/menu-plugin.d.ts +2 -0
  159. package/dist/service-portal/menu-plugin.js +353 -0
  160. package/dist/service-portal/menu-plugin.js.map +1 -0
  161. package/dist/service-portal/page-plugin.d.ts +2 -0
  162. package/dist/service-portal/page-plugin.js +702 -0
  163. package/dist/service-portal/page-plugin.js.map +1 -0
  164. package/dist/service-portal/portal-plugin.d.ts +2 -0
  165. package/dist/service-portal/portal-plugin.js +296 -0
  166. package/dist/service-portal/portal-plugin.js.map +1 -0
  167. package/dist/service-portal/theme-plugin.d.ts +2 -0
  168. package/dist/service-portal/theme-plugin.js +112 -0
  169. package/dist/service-portal/theme-plugin.js.map +1 -0
  170. package/dist/service-portal/utils.d.ts +8 -0
  171. package/dist/service-portal/utils.js +50 -0
  172. package/dist/service-portal/utils.js.map +1 -0
  173. package/dist/service-portal/widget-plugin.js +45 -8
  174. package/dist/service-portal/widget-plugin.js.map +1 -1
  175. package/dist/sla-plugin.js +2 -0
  176. package/dist/sla-plugin.js.map +1 -1
  177. package/dist/static-content-plugin.js +1 -0
  178. package/dist/static-content-plugin.js.map +1 -1
  179. package/dist/table-plugin.js +1 -0
  180. package/dist/table-plugin.js.map +1 -1
  181. package/dist/ui-action-plugin.js +2 -0
  182. package/dist/ui-action-plugin.js.map +1 -1
  183. package/dist/ui-page-plugin.js +33 -8
  184. package/dist/ui-page-plugin.js.map +1 -1
  185. package/dist/ui-policy-plugin.js +1 -0
  186. package/dist/ui-policy-plugin.js.map +1 -1
  187. package/dist/user-preference-plugin.js +2 -0
  188. package/dist/user-preference-plugin.js.map +1 -1
  189. package/dist/utils.d.ts +20 -2
  190. package/dist/utils.js +34 -3
  191. package/dist/utils.js.map +1 -1
  192. package/dist/ux-list-menu-config-plugin.js +2 -0
  193. package/dist/ux-list-menu-config-plugin.js.map +1 -1
  194. package/dist/view-plugin.js +1 -0
  195. package/dist/view-plugin.js.map +1 -1
  196. package/dist/workspace-plugin.js +2 -0
  197. package/dist/workspace-plugin.js.map +1 -1
  198. package/package.json +10 -11
  199. package/src/_types/eslint-community-eslint-utils.d.ts +15 -0
  200. package/src/acl-plugin.ts +97 -8
  201. package/src/applicability-plugin.ts +2 -0
  202. package/src/application-menu-plugin.ts +2 -0
  203. package/src/arrow-function-plugin.ts +128 -13
  204. package/src/atf/test-plugin.ts +2 -0
  205. package/src/basic-syntax-plugin.ts +21 -0
  206. package/src/call-expression-plugin.ts +1 -0
  207. package/src/claims-plugin.ts +1 -0
  208. package/src/client-script-plugin.ts +2 -1
  209. package/src/column-plugin.ts +1 -0
  210. package/src/cross-scope-privilege-plugin.ts +2 -1
  211. package/src/dashboard/dashboard-plugin.ts +2 -0
  212. package/src/data-plugin.ts +1 -0
  213. package/src/email-notification-plugin.ts +3 -23
  214. package/src/flow/constants/flow-plugin-constants.ts +1 -1
  215. package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +47 -45
  216. package/src/flow/flow-logic/flow-logic-plugin.ts +1 -0
  217. package/src/flow/plugins/approval-rules-plugin.ts +1 -0
  218. package/src/flow/plugins/flow-action-definition-plugin.ts +4 -2
  219. package/src/flow/plugins/flow-data-pill-plugin.ts +1 -0
  220. package/src/flow/plugins/flow-definition-plugin.ts +10 -4
  221. package/src/flow/plugins/flow-diagnostics-plugin.ts +1 -0
  222. package/src/flow/plugins/flow-instance-plugin.ts +103 -14
  223. package/src/flow/plugins/flow-trigger-instance-plugin.ts +1 -0
  224. package/src/flow/plugins/inline-script-plugin.ts +1 -0
  225. package/src/flow/plugins/step-definition-plugin.ts +3 -2
  226. package/src/flow/plugins/step-instance-plugin.ts +1 -0
  227. package/src/flow/plugins/trigger-plugin.ts +2 -0
  228. package/src/flow/plugins/wfa-datapill-plugin.ts +1 -0
  229. package/src/flow/post-install.ts +92 -0
  230. package/src/flow/utils/complex-objects.ts +10 -2
  231. package/src/flow/utils/flow-constants.ts +30 -1
  232. package/src/flow/utils/flow-to-xml.ts +4 -4
  233. package/src/flow/utils/label-cache-processor.ts +14 -2
  234. package/src/flow/utils/service-catalog.ts +5 -2
  235. package/src/form-plugin.ts +1411 -0
  236. package/src/html-import-plugin.ts +1 -0
  237. package/src/import-sets-plugin.ts +2 -0
  238. package/src/index.ts +9 -0
  239. package/src/instance-scan-plugin.ts +318 -0
  240. package/src/json-plugin.ts +1 -0
  241. package/src/list-plugin.ts +2 -1
  242. package/src/now-attach-plugin.ts +1 -0
  243. package/src/now-config-plugin.ts +833 -53
  244. package/src/now-id-plugin.ts +1 -0
  245. package/src/now-include-plugin.ts +1 -0
  246. package/src/now-ref-plugin.ts +1 -0
  247. package/src/now-unresolved-plugin.ts +1 -0
  248. package/src/package-json-plugin.ts +1 -0
  249. package/src/property-plugin.ts +3 -1
  250. package/src/record-plugin.ts +42 -2
  251. package/src/repack/lint/Rules.ts +171 -22
  252. package/src/repack/lint/index.ts +80 -56
  253. package/src/rest-api-plugin.ts +21 -1
  254. package/src/role-plugin.ts +2 -1
  255. package/src/schedule-script/index.ts +1 -0
  256. package/src/schedule-script/scheduled-script-plugin.ts +679 -0
  257. package/src/schedule-script/timeZoneConverter.ts +188 -0
  258. package/src/script-action-plugin.ts +2 -0
  259. package/src/script-include-plugin.ts +2 -0
  260. package/src/server-module-plugin/index.ts +14 -2
  261. package/src/service-catalog/catalog-clientscript-plugin.ts +2 -0
  262. package/src/service-catalog/catalog-item-plugin.ts +2 -0
  263. package/src/service-catalog/catalog-ui-policy-plugin.ts +2 -0
  264. package/src/service-catalog/sc-record-producer-plugin.ts +2 -0
  265. package/src/service-catalog/service-catalog-diagnostics.ts +30 -0
  266. package/src/service-catalog/shape-to-record.ts +8 -2
  267. package/src/service-catalog/variable-set-plugin.ts +2 -0
  268. package/src/service-portal/angular-provider-plugin.ts +2 -0
  269. package/src/service-portal/dependency-plugin.ts +6 -53
  270. package/src/service-portal/menu-plugin.ts +435 -0
  271. package/src/service-portal/page-plugin.ts +830 -0
  272. package/src/service-portal/portal-plugin.ts +319 -0
  273. package/src/service-portal/theme-plugin.ts +135 -0
  274. package/src/service-portal/utils.ts +69 -0
  275. package/src/service-portal/widget-plugin.ts +79 -9
  276. package/src/sla-plugin.ts +2 -0
  277. package/src/static-content-plugin.ts +1 -0
  278. package/src/table-plugin.ts +2 -1
  279. package/src/ui-action-plugin.ts +2 -0
  280. package/src/ui-page-plugin.ts +34 -8
  281. package/src/ui-policy-plugin.ts +2 -1
  282. package/src/user-preference-plugin.ts +2 -0
  283. package/src/utils.ts +42 -2
  284. package/src/ux-list-menu-config-plugin.ts +2 -0
  285. package/src/view-plugin.ts +1 -0
  286. package/src/workspace-plugin.ts +2 -0
  287. package/src/_types/eslint-plugin-es-x.d.ts +0 -17
@@ -0,0 +1,702 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SPPagePlugin = void 0;
7
+ const sdk_build_core_1 = require("@servicenow/sdk-build-core");
8
+ const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
9
+ const utils_1 = require("../utils");
10
+ const default_placeholder_dimensions = `{
11
+ "mobile": {
12
+ "height": "250px",
13
+ "width": "100%"
14
+ },
15
+ "desktop": {
16
+ "height": "250px",
17
+ "width": "100%"
18
+ },
19
+ "tablet": {
20
+ "height": "250px",
21
+ "width": "100%"
22
+ }
23
+ }`;
24
+ const default_placeholder_template = `<!--
25
+ AngularJS template with configurable options.
26
+ Use the "options" object to control dynamic behavior.
27
+ Example: Display an element when max row count is 10:
28
+ <div ng-if="options.maxRowCount === 10"></div>
29
+ The "skeleton-container" class is used for loading placeholders.
30
+ -->
31
+ <div class="skeleton-container">
32
+ <!-- Header Skeleton -->
33
+ <div class="skeleton-box skeleton-header"></div>
34
+ <!-- Body Skeleton -->
35
+ <div class="skeleton-box skeleton-line"></div>
36
+ <div class="skeleton-box skeleton-line small"></div>
37
+ <div class="skeleton-box skeleton-line medium"></div>
38
+ </div>`;
39
+ const default_placeholder_script = `function evaluateConfig(options) { return {
40
+ "mobile": {
41
+ "height": "250px",
42
+ "width": "100%"
43
+ },
44
+ "desktop": {
45
+ "height": "250px",
46
+ "width": "100%"
47
+ },
48
+ "tablet": {
49
+ "height": "250px",
50
+ "width": "100%"
51
+ }
52
+ }; }`;
53
+ const defaultValues = {
54
+ container: {
55
+ width: 'container',
56
+ backgroundStyle: 'default',
57
+ subheader: false,
58
+ bootstrapAlt: false,
59
+ },
60
+ instance: {
61
+ active: true,
62
+ color: 'default',
63
+ size: 'md',
64
+ asyncLoadDeviceType: 'desktop,tablet,mobile',
65
+ },
66
+ column: {
67
+ size: 12,
68
+ },
69
+ page: {
70
+ category: 'custom',
71
+ useSeoScript: false,
72
+ shortDescription: '',
73
+ public: false,
74
+ draft: false,
75
+ omitWatcher: false,
76
+ internal: false,
77
+ },
78
+ };
79
+ /**
80
+ * Safely parse a size value from a Shape, handling non-numeric strings
81
+ * @param shape - The shape to extract the size from
82
+ * @param fieldName - The field name to extract (e.g., "size", "size_sm")
83
+ * @param defaultValue - Default value if parsing fails
84
+ * @returns Numeric size value or undefined
85
+ */
86
+ /**
87
+ * Sort an array of shapes by their order field
88
+ * @param shapes - Array of shapes to sort
89
+ * @returns Sorted array
90
+ */
91
+ function sortByOrder(shapes) {
92
+ return shapes.sort((a, b) => {
93
+ const aOrder = (0, utils_1.getFieldAsNumber)(a, 'order', 1);
94
+ const bOrder = (0, utils_1.getFieldAsNumber)(b, 'order', 1);
95
+ return (aOrder ?? 1) - (bOrder ?? 1);
96
+ });
97
+ }
98
+ /**
99
+ * Conditionally adds a property to an object if the value is not empty or undefined.
100
+ * Filters out undefined values, empty arrays, and empty strings to keep objects clean.
101
+ * @param obj - The target object to add the property to
102
+ * @param key - The property key to add
103
+ * @param value - The value to add (will be filtered if empty/undefined)
104
+ */
105
+ const addProperty = (obj, key, value, objectType) => {
106
+ if (value === undefined ||
107
+ (Array.isArray(value) && value.length === 0) ||
108
+ (typeof value === 'string' && value === '')) {
109
+ return;
110
+ }
111
+ // Check if value matches default for this object type
112
+ if (objectType && defaultValues[objectType] && defaultValues[objectType][key] === value) {
113
+ return;
114
+ }
115
+ obj[key] = value;
116
+ };
117
+ /**
118
+ * Creates a container object from a ServiceNow sp_container record Shape.
119
+ * Transforms database fields to Fluent API format and includes nested rows.
120
+ * @param container - The sp_container record Shape
121
+ * @param rows - Array of row objects that belong to this container
122
+ * @returns Formatted container object or undefined if container is empty
123
+ */
124
+ const getContainerObject = (container, rows) => {
125
+ if (!container || (0, isEmpty_1.default)(container)) {
126
+ return;
127
+ }
128
+ const name = container.get('name').ifString()?.getValue();
129
+ const width = container.get('width').ifString()?.getValue();
130
+ const backgroundStyle = container.get('background_style').ifString()?.getValue();
131
+ const backgroundColor = container.get('background_color').ifString()?.getValue();
132
+ const backgroundImage = container.get('background_image').ifString()?.getValue();
133
+ const cssClass = container.get('class_name').ifString()?.getValue();
134
+ const parentClass = container.get('container_class_name').ifString()?.getValue();
135
+ const subheader = container.get('subheader').toBoolean()?.getValue();
136
+ const bootstrapAlt = container.get('bootstrap_alt').toBoolean()?.getValue();
137
+ const semanticTag = container.get('semantic_tag').ifString()?.getValue();
138
+ const title = container.get('title').ifString()?.getValue();
139
+ const containerObject = {};
140
+ addProperty(containerObject, '$id', container.getId());
141
+ addProperty(containerObject, 'order', (0, utils_1.getFieldAsNumber)(container, 'order', 1));
142
+ addProperty(containerObject, 'name', name);
143
+ addProperty(containerObject, 'width', width, 'container');
144
+ addProperty(containerObject, 'backgroundStyle', backgroundStyle, 'container');
145
+ addProperty(containerObject, 'backgroundColor', backgroundColor, 'container');
146
+ addProperty(containerObject, 'backgroundImage', backgroundImage);
147
+ addProperty(containerObject, 'cssClass', cssClass);
148
+ addProperty(containerObject, 'parentClass', parentClass);
149
+ addProperty(containerObject, 'subheader', subheader, 'container');
150
+ addProperty(containerObject, 'bootstrapAlt', bootstrapAlt, 'container');
151
+ addProperty(containerObject, 'semanticTag', semanticTag);
152
+ addProperty(containerObject, 'title', title);
153
+ addProperty(containerObject, 'rows', rows);
154
+ return containerObject;
155
+ };
156
+ /**
157
+ * Creates a row object from a ServiceNow sp_row record Shape.
158
+ * Transforms database fields to Fluent API format and includes nested columns.
159
+ * @param row - The sp_row record Shape
160
+ * @param columns - Array of column objects that belong to this row
161
+ * @returns Formatted row object or undefined if row is empty
162
+ */
163
+ const getRowObject = (row, columns) => {
164
+ if (!row || (0, isEmpty_1.default)(row)) {
165
+ return;
166
+ }
167
+ const cssClass = row.get('class_name').ifString()?.getValue();
168
+ const semanticTag = row.get('semantic_tag').ifString()?.getValue();
169
+ const rowObject = {};
170
+ addProperty(rowObject, '$id', row.getId());
171
+ addProperty(rowObject, 'cssClass', cssClass);
172
+ addProperty(rowObject, 'semanticTag', semanticTag);
173
+ addProperty(rowObject, 'order', (0, utils_1.getFieldAsNumber)(row, 'order', 1));
174
+ addProperty(rowObject, 'columns', columns);
175
+ return rowObject;
176
+ };
177
+ /**
178
+ * Creates a column object from a ServiceNow sp_column record Shape.
179
+ * @param column - The sp_column record Shape
180
+ * @param instances - Array of instance objects that belong to this column
181
+ * @param nestedRows - Array of nested row objects within this column
182
+ * @returns Formatted column object or undefined if column is empty
183
+ */
184
+ const getColumnObject = (column, instances, nestedRows) => {
185
+ if (!column || (0, isEmpty_1.default)(column)) {
186
+ return;
187
+ }
188
+ const cssClass = column.get('class_name').ifString()?.getValue();
189
+ const semanticTag = column.get('semantic_tag').ifString()?.getValue();
190
+ const columnObject = {};
191
+ addProperty(columnObject, '$id', column.getId());
192
+ addProperty(columnObject, 'size', (0, utils_1.getFieldAsNumber)(column, 'size', 12), 'column');
193
+ addProperty(columnObject, 'sizeSm', (0, utils_1.getFieldAsNumber)(column, 'size_sm'));
194
+ addProperty(columnObject, 'sizeLg', (0, utils_1.getFieldAsNumber)(column, 'size_lg'));
195
+ addProperty(columnObject, 'sizeXs', (0, utils_1.getFieldAsNumber)(column, 'size_xs'));
196
+ addProperty(columnObject, 'cssClass', cssClass);
197
+ addProperty(columnObject, 'semanticTag', semanticTag);
198
+ addProperty(columnObject, 'order', (0, utils_1.getFieldAsNumber)(column, 'order', 1));
199
+ addProperty(columnObject, 'instances', instances);
200
+ addProperty(columnObject, 'nestedRows', nestedRows);
201
+ return columnObject;
202
+ };
203
+ /**
204
+ * Extracts and parses roles from a ServiceNow instance record.
205
+ * Converts comma-separated role string to an array of role names.
206
+ * @param instance - The sp_instance record Shape
207
+ * @returns Array of role names or undefined if no roles exist
208
+ */
209
+ const getRolesArray = (instance) => {
210
+ const rolesStr = instance.get('roles').ifString()?.getValue();
211
+ if (!rolesStr || rolesStr === '') {
212
+ return;
213
+ }
214
+ const rolesArray = rolesStr
215
+ .split(',')
216
+ .map((role) => role.trim())
217
+ .filter((role) => role !== '');
218
+ return rolesArray.length > 0 ? rolesArray : undefined;
219
+ };
220
+ /**
221
+ * Creates an instance object from a ServiceNow sp_instance record Shape.
222
+ * Transforms all instance properties from database format to Fluent API format,
223
+ * including widget references, styling, roles, and configuration.
224
+ * @param instance - The sp_instance record Shape
225
+ * @returns Formatted instance object or undefined if instance is empty
226
+ */
227
+ function getInstanceObject(instance) {
228
+ if (!instance || (0, isEmpty_1.default)(instance)) {
229
+ return;
230
+ }
231
+ const title = instance.get('title').ifString()?.getValue();
232
+ const id = instance.get('id').ifString()?.getValue();
233
+ const widget = instance.get('sp_widget').ifString()?.getValue();
234
+ const widgetParameters = instance.get('widget_parameters').ifString()?.getValue();
235
+ const css = instance.get('css').ifString()?.getValue();
236
+ const url = instance.get('url').ifString()?.getValue();
237
+ const glyph = instance.get('glyph').ifString()?.getValue();
238
+ const size = instance.get('size').ifString()?.getValue();
239
+ const color = instance.get('color').ifString()?.getValue();
240
+ const cssClass = instance.get('class_name').ifString()?.getValue();
241
+ const shortDescription = instance.get('short_description').ifString()?.getValue();
242
+ const active = instance.get('active').toBoolean()?.getValue();
243
+ const instanceObject = {};
244
+ addProperty(instanceObject, '$id', instance.getId());
245
+ addProperty(instanceObject, 'title', title);
246
+ addProperty(instanceObject, 'id', id);
247
+ addProperty(instanceObject, 'widget', widget);
248
+ addProperty(instanceObject, 'widgetParameters', widgetParameters);
249
+ addProperty(instanceObject, 'css', css);
250
+ addProperty(instanceObject, 'url', url);
251
+ addProperty(instanceObject, 'glyph', glyph);
252
+ addProperty(instanceObject, 'size', size, 'instance');
253
+ addProperty(instanceObject, 'color', color, 'instance');
254
+ addProperty(instanceObject, 'cssClass', cssClass);
255
+ addProperty(instanceObject, 'active', active, 'instance');
256
+ addProperty(instanceObject, 'order', (0, utils_1.getFieldAsNumber)(instance, 'order', 1));
257
+ addProperty(instanceObject, 'roles', getRolesArray(instance));
258
+ addProperty(instanceObject, 'shortDescription', shortDescription);
259
+ return instanceObject;
260
+ }
261
+ /**
262
+ * Converts an ArrayShape of roles to a comma-separated string.
263
+ * Handles both role record objects and string values, removes duplicates and empty values.
264
+ * @param roles - ArrayShape containing role records or strings
265
+ * @returns Comma-separated string of unique role names or undefined if no roles
266
+ */
267
+ function getRolesString(roles) {
268
+ if (!roles) {
269
+ return;
270
+ }
271
+ const uniqueRoles = [
272
+ ...new Set(roles.getElements().map((role) => {
273
+ const roleName = role.isRecord()
274
+ ? role.get('name')?.ifString()?.getValue()
275
+ : role.ifString()?.getValue();
276
+ return (roleName ?? '').trim();
277
+ })),
278
+ ];
279
+ return uniqueRoles.filter((role) => role !== '').join(',');
280
+ }
281
+ /**
282
+ * Recursively processes nested rows within a column
283
+ * @param columnRows - Rows that belong to the column
284
+ * @param allColumns - All available columns
285
+ * @param allInstances - All available instances
286
+ * @returns Array of processed SPRow objects with nested structure
287
+ */
288
+ function getNestedRows(columnRows, allRows, allColumns, allInstances) {
289
+ if (!columnRows || columnRows.length === 0) {
290
+ return [];
291
+ }
292
+ // Sort rows by order
293
+ const sortedRows = sortByOrder(columnRows);
294
+ return sortedRows
295
+ .map((row) => {
296
+ const rowId = row.getId();
297
+ // Get columns for this nested row
298
+ const rowColumns = sortByOrder(allColumns.filter((column) => column.get('sp_row').equals(rowId)));
299
+ const columns = rowColumns
300
+ .map((column) => {
301
+ const columnId = column.getId();
302
+ // Get instances for this column
303
+ const columnInstances = sortByOrder(allInstances.filter((instance) => instance.get('sp_column').equals(columnId)));
304
+ // Recursively get nested rows for this column
305
+ const nestedColumnRows = allRows.filter((row) => row.get('sp_column').equals(columnId));
306
+ const nestedRows = getNestedRows(nestedColumnRows, allRows, allColumns, allInstances);
307
+ const instances = columnInstances
308
+ .map((instance) => {
309
+ return getInstanceObject(instance);
310
+ })
311
+ .filter((instanceObject) => Boolean(instanceObject));
312
+ return getColumnObject(column, instances, nestedRows);
313
+ })
314
+ .filter((col) => Boolean(col));
315
+ const rowObj = getRowObject(row, columns);
316
+ return rowObj;
317
+ })
318
+ .filter((row) => Boolean(row));
319
+ }
320
+ /**
321
+ * Generates a container name from the container shape or creates a default name.
322
+ * Uses the explicit name if provided, otherwise generates a name based on page title and order.
323
+ * @param $ - The container shape object
324
+ * @param pageTitle - The title of the parent page
325
+ * @param index - The zero-based index of the container in the page
326
+ * @returns The container name string
327
+ */
328
+ const getContainerName = ($, pageTitle, index) => {
329
+ let name = $.get('name').ifString()?.getValue();
330
+ if (!name) {
331
+ const order = $.get('order').ifNumber()?.getValue() || index + 1;
332
+ name = `${pageTitle} - Container ${order}`;
333
+ }
334
+ return name;
335
+ };
336
+ /**
337
+ * Creates ServiceNow sp_container records from Fluent container shapes and their nested rows/columns/instances.
338
+ *
339
+ * @param containersArray - Array of Fluent container Shape objects to transform
340
+ * @param pageId - RecordId of the parent sp_page record that owns these containers
341
+ * @param pageTitle - Title of the parent page, used for generating default container names
342
+ * @param factory - Factory instance for creating ServiceNow records with proper relationships
343
+ * @returns Promise that resolves to an array of all created records (containers, rows, columns, instances)
344
+ */
345
+ const createContainerRecords = async (containersArray, pageId, pageTitle, factory) => {
346
+ const records = [];
347
+ for (let index = 0; index < containersArray.length; index++) {
348
+ const containerShape = containersArray[index];
349
+ if (containerShape?.isObject()) {
350
+ const container = containerShape.asObject();
351
+ const name = getContainerName(container, pageTitle, index);
352
+ const containerRecord = await factory.createRecord({
353
+ source: containerShape,
354
+ table: 'sp_container',
355
+ explicitId: container.get('$id'),
356
+ properties: container.transform(({ $ }) => ({
357
+ name: $.val(name),
358
+ sp_page: $.val(pageId),
359
+ width: $.from('width').def('container'),
360
+ background_style: $.from('backgroundStyle').def('default'),
361
+ background_color: $.from('backgroundColor').def(''),
362
+ background_image: $.from('backgroundImage').def(''),
363
+ class_name: $.from('cssClass').def(''),
364
+ container_class_name: $.from('parentClass').def(''),
365
+ subheader: $.from('subheader').def(false),
366
+ bootstrap_alt: $.from('bootstrapAlt').def(false),
367
+ semantic_tag: $.from('semanticTag').def(''),
368
+ title: $.from('title').def(''),
369
+ order: $.from('order').def(index + 1),
370
+ })),
371
+ });
372
+ records.push(containerRecord);
373
+ // Handle rows
374
+ const rows = container.get('rows').ifArray()?.getElements() || [];
375
+ const rowRecords = await createRowRecords(rows, containerRecord.getId(), factory, undefined);
376
+ records.push(...rowRecords);
377
+ }
378
+ }
379
+ return records;
380
+ };
381
+ /**
382
+ * Creates ServiceNow sp_row records from Fluent row shapes and their nested columns/instances.
383
+ *
384
+ * @param rowsArray - Array of Fluent row Shape objects to transform
385
+ * @param containerId - RecordId of the parent sp_container record that owns these rows
386
+ * @param factory - Factory instance for creating ServiceNow records with proper relationships
387
+ * @param columnId - RecordId of the parent sp_column record (for nested rows within columns)
388
+ * @returns Promise that resolves to an array of all created records (rows, columns, instances)
389
+ */
390
+ const createRowRecords = async (rowsArray, containerId, factory, columnId) => {
391
+ const records = [];
392
+ for (let index = 0; index < rowsArray.length; index++) {
393
+ const rowShape = rowsArray[index];
394
+ if (rowShape?.isObject()) {
395
+ const row = rowShape.asObject();
396
+ const rowRecord = await factory.createRecord({
397
+ source: rowShape,
398
+ table: 'sp_row',
399
+ explicitId: row.get('$id'),
400
+ properties: row.transform(({ $ }) => ({
401
+ sp_container: $.val(containerId),
402
+ class_name: $.from('cssClass').def(''),
403
+ semantic_tag: $.from('semanticTag').def(''),
404
+ order: $.from('order').def(index + 1),
405
+ sp_column: $.val(columnId),
406
+ })),
407
+ });
408
+ records.push(rowRecord);
409
+ // Handle columns
410
+ const columns = row.get('columns').ifArray()?.getElements() || [];
411
+ const columnRecords = await createColumnRecords(columns, rowRecord.getId(), factory);
412
+ records.push(...columnRecords);
413
+ }
414
+ }
415
+ return records;
416
+ };
417
+ /**
418
+ * Creates ServiceNow sp_column records from Fluent column shapes and their nested instances/rows.
419
+ *
420
+ * @param columnsArray - Array of Fluent column Shape objects to transform
421
+ * @param rowId - RecordId of the parent sp_row record that owns these columns
422
+ * @param factory - Factory instance for creating ServiceNow records with proper relationships
423
+ * @returns Promise that resolves to an array of all created records (columns, instances, nested rows)
424
+ */
425
+ async function createColumnRecords(columnsArray, rowId, factory) {
426
+ const records = [];
427
+ for (let index = 0; index < columnsArray.length; index++) {
428
+ const columnShape = columnsArray[index];
429
+ if (columnShape?.isObject()) {
430
+ const column = columnShape.asObject();
431
+ const columnRecord = await factory.createRecord({
432
+ source: columnShape,
433
+ table: 'sp_column',
434
+ explicitId: column.get('$id'),
435
+ properties: column.transform(({ $ }) => ({
436
+ sp_row: $.val(rowId),
437
+ size: $.from('size').def(12),
438
+ size_sm: $.from('sizeSm'),
439
+ size_lg: $.from('sizeLg'),
440
+ size_xs: $.from('sizeXs'),
441
+ class_name: $.from('cssClass').def(''),
442
+ semantic_tag: $.from('semanticTag').def(''),
443
+ order: $.from('order').def(index + 1),
444
+ })),
445
+ });
446
+ records.push(columnRecord);
447
+ // Handle instances
448
+ const instances = column.get('instances').ifArray()?.getElements() || [];
449
+ const nestedRows = column.get('nestedRows').ifArray()?.getElements() || [];
450
+ const nestedRowRecords = await createRowRecords(nestedRows, undefined, factory, columnRecord.getId());
451
+ records.push(...nestedRowRecords);
452
+ const instanceRecords = await createInstanceRecords(instances, columnRecord.getId(), factory);
453
+ records.push(...instanceRecords);
454
+ }
455
+ }
456
+ return records;
457
+ }
458
+ /**
459
+ * Creates ServiceNow sp_instance records from Fluent instance shapes.
460
+ *
461
+ * @param instancesArray - Array of Fluent instance Shape objects to transform
462
+ * @param columnId - RecordId of the parent sp_column record that owns these instances
463
+ * @param factory - Factory instance for creating ServiceNow records with proper relationships
464
+ * @returns Promise that resolves to an array of all created instance records
465
+ */
466
+ async function createInstanceRecords(instancesArray, columnId, factory) {
467
+ const records = [];
468
+ for (let index = 0; index < instancesArray.length; index++) {
469
+ const instanceShape = instancesArray[index];
470
+ if (instanceShape?.isObject()) {
471
+ const instance = instanceShape.asObject();
472
+ // Process roles if they exist as an array
473
+ const rolesArray = instance.get('roles').ifArray();
474
+ const rolesString = getRolesString(rolesArray);
475
+ const instanceRecord = await factory.createRecord({
476
+ source: instanceShape,
477
+ table: 'sp_instance',
478
+ explicitId: instance.get('$id'),
479
+ properties: instance.transform(({ $ }) => ({
480
+ sp_column: $.val(columnId),
481
+ title: $.from('title').def(''),
482
+ id: $.from('id').def(''),
483
+ sp_widget: $.from('widget').map(utils_1.toReference).def(''),
484
+ widget_parameters: $.from('widgetParameters').def(''),
485
+ short_description: $.from('shortDescription').def(''),
486
+ css: $.from('css').def(''),
487
+ url: $.from('url').def(''),
488
+ glyph: $.from('glyph').def(''),
489
+ size: $.from('size').def('md'),
490
+ color: $.from('color').def('default'),
491
+ class_name: $.from('cssClass').def(''),
492
+ active: $.from('active').def(defaultValues.instance.active),
493
+ order: $.from('order').def(index + 1),
494
+ roles: $.val(rolesString).def(''),
495
+ async_load: $.from('asyncLoad').def(false),
496
+ async_load_trigger: $.from('asyncLoadTrigger').def('viewport'),
497
+ async_load_device_type: $.def(defaultValues.instance.asyncLoadDeviceType),
498
+ preserve_placeholder_size: $.def(false),
499
+ placeholder_dimensions: $.def(default_placeholder_dimensions),
500
+ advanced_placeholder_dimensions: $.def(false),
501
+ placeholder_dimensions_script: $.def(default_placeholder_script),
502
+ placeholder_template: $.def(default_placeholder_template),
503
+ })),
504
+ });
505
+ records.push(instanceRecord);
506
+ }
507
+ }
508
+ return records;
509
+ }
510
+ exports.SPPagePlugin = sdk_build_core_1.Plugin.create({
511
+ name: 'SPPagePlugin',
512
+ docs: [(0, utils_1.createSdkDocEntry)('SPPage', ['sp_page'])],
513
+ records: {
514
+ sp_page: {
515
+ coalesce: ['id'],
516
+ relationships: {
517
+ sp_container: {
518
+ via: 'sp_page',
519
+ descendant: true,
520
+ relationships: {
521
+ sp_row: {
522
+ via: 'sp_container',
523
+ descendant: true,
524
+ relationships: {
525
+ sp_column: {
526
+ via: 'sp_row',
527
+ descendant: true,
528
+ relationships: {
529
+ sp_instance: {
530
+ via: 'sp_column',
531
+ descendant: true,
532
+ },
533
+ sp_row: {
534
+ via: 'sp_column',
535
+ descendant: true,
536
+ },
537
+ },
538
+ },
539
+ },
540
+ },
541
+ },
542
+ },
543
+ },
544
+ toShape(record, { descendants }) {
545
+ // Build hierarchical structure from descendants in a single pass
546
+ // to avoid "node that was removed or forgotten" errors
547
+ // Get all descendants at once to avoid multiple queries
548
+ const allContainers = sortByOrder(descendants
549
+ .query('sp_container')
550
+ .filter((container) => container.get('sp_page').equals(record.getId())));
551
+ const allRows = descendants.query('sp_row');
552
+ const allColumns = descendants.query('sp_column');
553
+ const allInstances = descendants.query('sp_instance');
554
+ const containers = allContainers.map((container) => {
555
+ const containerId = container.getId();
556
+ // Get rows for this container
557
+ const containerRows = sortByOrder(allRows.filter((row) => row.get('sp_container').equals(containerId)));
558
+ const rows = containerRows
559
+ .map((row) => {
560
+ const rowId = row.getId();
561
+ // Get columns for this row
562
+ const rowColumns = sortByOrder(allColumns.filter((column) => column.get('sp_row').equals(rowId)));
563
+ const columns = rowColumns
564
+ .map((column) => {
565
+ const columnId = column.getId();
566
+ // Get instances for this column
567
+ const columnInstances = sortByOrder(allInstances.filter((instance) => instance.get('sp_column').equals(columnId)));
568
+ const columnRows = allRows.filter((row) => row.get('sp_column').equals(columnId));
569
+ const nestedRows = getNestedRows(columnRows, allRows, allColumns, allInstances);
570
+ const instances = columnInstances
571
+ .map((instance) => {
572
+ return getInstanceObject(instance);
573
+ })
574
+ .filter((instanceObject) => Boolean(instanceObject));
575
+ return getColumnObject(column, instances, nestedRows);
576
+ })
577
+ .filter((columnObject) => Boolean(columnObject));
578
+ return getRowObject(row, columns);
579
+ })
580
+ .filter((rowObject) => Boolean(rowObject));
581
+ return getContainerObject(container, rows);
582
+ });
583
+ // Process roles to check if they should be included
584
+ const rolesArray = getRolesArray(record);
585
+ return {
586
+ success: true,
587
+ value: new sdk_build_core_1.CallExpressionShape({
588
+ source: record,
589
+ callee: 'SPPage',
590
+ args: [
591
+ record.transform(({ $ }) => {
592
+ const pageObject = {
593
+ title: $,
594
+ category: $,
595
+ pageId: $.from('id').def(''),
596
+ draft: $.toBoolean().def(false),
597
+ internal: $.toBoolean().def(false),
598
+ omitWatcher: $.from('omit_watcher').toBoolean().def(false),
599
+ public: $.toBoolean().def(false),
600
+ useSeoScript: $.from('use_seo_script').toBoolean().def(false),
601
+ css: $.def(''),
602
+ shortDescription: $.from('short_description').def(''),
603
+ seoScript: $.from('seo_script').def(''),
604
+ dynamicTitleStructure: $.from('dynamic_title_structure').def(''),
605
+ humanReadableUrlStructure: $.from('human_readable_url_structure').def(''),
606
+ };
607
+ // Only add roles if they exist
608
+ if (rolesArray) {
609
+ pageObject['roles'] = $.val(rolesArray);
610
+ }
611
+ // Only add containers if they exist
612
+ if (containers.length > 0) {
613
+ pageObject['containers'] = $.val(containers);
614
+ }
615
+ return pageObject;
616
+ }),
617
+ ],
618
+ }),
619
+ };
620
+ },
621
+ },
622
+ },
623
+ shapes: [
624
+ {
625
+ shape: sdk_build_core_1.CallExpressionShape,
626
+ fileTypes: ['fluent'],
627
+ async toRecord(callExpression, { diagnostics, factory }) {
628
+ if (callExpression.getCallee() !== 'SPPage') {
629
+ return { success: false };
630
+ }
631
+ const page = callExpression.getArgument(0).asObject();
632
+ const containers = page.get('containers').ifArray()?.getElements() || [];
633
+ const useSeoScriptShape = page.get('useSeoScript');
634
+ const useSeoScript = useSeoScriptShape.ifBoolean()?.getValue() ?? false;
635
+ const seoScriptRef = (0, utils_1.toReference)(page.get('seoScript'));
636
+ const seoScript = typeof seoScriptRef === 'string' ? seoScriptRef : seoScriptRef.getValue();
637
+ if (useSeoScript && (!seoScript || seoScript.trim() === '')) {
638
+ diagnostics.error(useSeoScriptShape.getOriginalNode(), `Invalid SPPage configuration: when "useSeoScript" is true, "seoScript" must be added.`);
639
+ }
640
+ // Process roles if they exist as an array
641
+ const rolesArray = page.get('roles').ifArray();
642
+ const rolesString = getRolesString(rolesArray);
643
+ const pageIdShape = page.get('pageId');
644
+ const pageId = pageIdShape.asString().getValue();
645
+ if (!pageId.trim()) {
646
+ diagnostics.error(pageIdShape.getOriginalNode(), 'Invalid SPPage configuration: "pageId" must be a non-empty string.');
647
+ }
648
+ const urlStructureShape = page.get('humanReadableUrlStructure');
649
+ const urlStructure = urlStructureShape.ifString()?.getValue();
650
+ if (urlStructure && urlStructure.length > 0) {
651
+ const delimiter = String(Math.floor(Math.random() * 100000));
652
+ const urlStrings = urlStructure
653
+ .replaceAll(/[/-]/g, delimiter)
654
+ .replaceAll('%', delimiter + '%')
655
+ .split(delimiter);
656
+ const nonVariables = [];
657
+ for (const segment of urlStrings) {
658
+ if (segment.length > 1 && segment.indexOf('%') === 0) {
659
+ continue;
660
+ }
661
+ nonVariables.push(segment);
662
+ }
663
+ if (!/^[a-zA-Z0-9/-]*$/.test(nonVariables.join(''))) {
664
+ diagnostics.error(urlStructureShape.getOriginalNode(), `Only alphanumeric characters, - and / are allowed in humanReadableUrlStructure.`);
665
+ }
666
+ if (urlStructure.indexOf('/') !== urlStructure.lastIndexOf('/')) {
667
+ diagnostics.error(urlStructureShape.getOriginalNode(), `No more than one "/" character is allowed in humanReadableUrlStructure.`);
668
+ }
669
+ }
670
+ const title = page.get('title').ifString()?.getValue() || pageId;
671
+ // Create the main page record
672
+ const pageRecord = await factory.createRecord({
673
+ source: callExpression,
674
+ table: 'sp_page',
675
+ properties: page.transform(({ $ }) => ({
676
+ id: $.from('pageId'),
677
+ title: $.val(title),
678
+ category: $.def('custom'),
679
+ css: $.def(''),
680
+ draft: $.def(false),
681
+ dynamic_title_structure: $.from('dynamicTitleStructure').def(''),
682
+ human_readable_url_structure: $.from('humanReadableUrlStructure').def(''),
683
+ internal: $.def(false),
684
+ omit_watcher: $.from('omitWatcher').def(false),
685
+ public: $.def(false),
686
+ roles: $.val(rolesString).def(''),
687
+ seo_script: $.from('seoScript').map(utils_1.toReference).def(''),
688
+ short_description: $.from('shortDescription').def(''),
689
+ use_seo_script: $.from('useSeoScript').def(false),
690
+ })),
691
+ });
692
+ // Create container, row, column, and instance records
693
+ const allRecords = await createContainerRecords(containers, pageRecord.getId(), title, factory);
694
+ return {
695
+ success: true,
696
+ value: pageRecord.with(...allRecords),
697
+ };
698
+ },
699
+ },
700
+ ],
701
+ });
702
+ //# sourceMappingURL=page-plugin.js.map