@servicenow/sdk-build-plugins 4.6.1 → 4.7.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.
- package/dist/acl-plugin.js +0 -3
- package/dist/acl-plugin.js.map +1 -1
- package/dist/applicability-plugin.js +0 -2
- package/dist/applicability-plugin.js.map +1 -1
- package/dist/application-menu-plugin.js +0 -2
- package/dist/application-menu-plugin.js.map +1 -1
- package/dist/arrow-function-plugin.js +0 -1
- package/dist/arrow-function-plugin.js.map +1 -1
- package/dist/atf/test-plugin.js +0 -2
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +0 -1
- package/dist/basic-syntax-plugin.js.map +1 -1
- package/dist/business-rule-plugin.js +0 -1
- package/dist/business-rule-plugin.js.map +1 -1
- package/dist/call-expression-plugin.js +0 -1
- package/dist/call-expression-plugin.js.map +1 -1
- package/dist/claims-plugin.js +0 -1
- package/dist/claims-plugin.js.map +1 -1
- package/dist/client-script-plugin.js +0 -1
- package/dist/client-script-plugin.js.map +1 -1
- package/dist/column-plugin.js +24 -7
- package/dist/column-plugin.js.map +1 -1
- package/dist/cross-scope-privilege-plugin.js +0 -1
- package/dist/cross-scope-privilege-plugin.js.map +1 -1
- package/dist/dashboard/dashboard-plugin.js +0 -2
- package/dist/dashboard/dashboard-plugin.js.map +1 -1
- package/dist/data-plugin.js +0 -1
- package/dist/data-plugin.js.map +1 -1
- package/dist/data-policy-plugin.d.ts +2 -0
- package/dist/data-policy-plugin.js +276 -0
- package/dist/data-policy-plugin.js.map +1 -0
- package/dist/email-notification-plugin.js +2 -3
- package/dist/email-notification-plugin.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-constants.d.ts +2 -0
- package/dist/flow/flow-logic/flow-logic-constants.js +6 -1
- package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-diagnostics.js +192 -56
- package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +2 -1
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +44 -5
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-plugin.js +279 -29
- package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-shapes.d.ts +15 -0
- package/dist/flow/flow-logic/flow-logic-shapes.js +25 -1
- package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -1
- package/dist/flow/plugins/approval-rules-plugin.js +0 -1
- package/dist/flow/plugins/approval-rules-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-action-definition-plugin.js +804 -205
- package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-data-pill-plugin.js +3 -5
- package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-definition-plugin.js +84 -17
- package/dist/flow/plugins/flow-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-diagnostics-plugin.js +65 -3
- package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-instance-plugin.js +13 -5
- package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-trigger-instance-plugin.js +0 -1
- package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/inline-script-plugin.js +0 -1
- package/dist/flow/plugins/inline-script-plugin.js.map +1 -1
- package/dist/flow/plugins/step-definition-plugin.js +0 -2
- package/dist/flow/plugins/step-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/step-instance-plugin.js +216 -77
- package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/trigger-plugin.js +0 -2
- package/dist/flow/plugins/trigger-plugin.js.map +1 -1
- package/dist/flow/plugins/wfa-datapill-plugin.js +0 -1
- package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -1
- package/dist/flow/utils/datapill-transformer.js +9 -5
- package/dist/flow/utils/datapill-transformer.js.map +1 -1
- package/dist/flow/utils/flow-constants.d.ts +12 -0
- package/dist/flow/utils/flow-constants.js +17 -3
- package/dist/flow/utils/flow-constants.js.map +1 -1
- package/dist/flow/utils/flow-io-to-record.d.ts +1 -1
- package/dist/flow/utils/flow-io-to-record.js +21 -13
- package/dist/flow/utils/flow-io-to-record.js.map +1 -1
- package/dist/flow/utils/flow-pill-utils.d.ts +26 -0
- package/dist/flow/utils/flow-pill-utils.js +50 -0
- package/dist/flow/utils/flow-pill-utils.js.map +1 -0
- package/dist/flow/utils/flow-stage-processor.d.ts +138 -0
- package/dist/flow/utils/flow-stage-processor.js +665 -0
- package/dist/flow/utils/flow-stage-processor.js.map +1 -0
- package/dist/flow/utils/pill-string-parser.js +28 -43
- package/dist/flow/utils/pill-string-parser.js.map +1 -1
- package/dist/flow/utils/utils.d.ts +11 -6
- package/dist/flow/utils/utils.js +37 -28
- package/dist/flow/utils/utils.js.map +1 -1
- package/dist/form-plugin.js +4 -14
- package/dist/form-plugin.js.map +1 -1
- package/dist/html-import-plugin.js +0 -1
- package/dist/html-import-plugin.js.map +1 -1
- package/dist/import-sets-plugin.js +0 -2
- package/dist/import-sets-plugin.js.map +1 -1
- package/dist/inbound-email-action-plugin.js +0 -1
- package/dist/inbound-email-action-plugin.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/instance-scan-plugin.js +0 -7
- package/dist/instance-scan-plugin.js.map +1 -1
- package/dist/json-plugin.js +0 -1
- package/dist/json-plugin.js.map +1 -1
- package/dist/list-plugin.js +4 -1
- package/dist/list-plugin.js.map +1 -1
- package/dist/now-attach-plugin.js +0 -1
- package/dist/now-attach-plugin.js.map +1 -1
- package/dist/now-config-plugin.js +0 -1
- package/dist/now-config-plugin.js.map +1 -1
- package/dist/now-id-plugin.js +0 -1
- package/dist/now-id-plugin.js.map +1 -1
- package/dist/now-include-plugin.js +0 -1
- package/dist/now-include-plugin.js.map +1 -1
- package/dist/now-ref-plugin.js +0 -1
- package/dist/now-ref-plugin.js.map +1 -1
- package/dist/now-unresolved-plugin.js +0 -1
- package/dist/now-unresolved-plugin.js.map +1 -1
- package/dist/package-json-plugin.js +3 -2
- package/dist/package-json-plugin.js.map +1 -1
- package/dist/property-plugin.js +0 -2
- package/dist/property-plugin.js.map +1 -1
- package/dist/record-plugin.d.ts +2 -0
- package/dist/record-plugin.js +2 -2
- package/dist/record-plugin.js.map +1 -1
- package/dist/repack/lint/Rules.d.ts +1 -2
- package/dist/rest-api-plugin.js +6 -5
- package/dist/rest-api-plugin.js.map +1 -1
- package/dist/role-plugin.js +0 -1
- package/dist/role-plugin.js.map +1 -1
- package/dist/schedule-script/scheduled-script-plugin.js +5 -4
- package/dist/schedule-script/scheduled-script-plugin.js.map +1 -1
- package/dist/script-action-plugin.js +0 -2
- package/dist/script-action-plugin.js.map +1 -1
- package/dist/script-include-plugin.js +0 -4
- package/dist/script-include-plugin.js.map +1 -1
- package/dist/server-module-plugin/index.js +2 -3
- package/dist/server-module-plugin/index.js.map +1 -1
- package/dist/service-catalog/catalog-clientscript-plugin.js +0 -2
- package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -1
- package/dist/service-catalog/catalog-item-plugin.js +0 -2
- package/dist/service-catalog/catalog-item-plugin.js.map +1 -1
- package/dist/service-catalog/catalog-ui-policy-plugin.js +0 -2
- package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -1
- package/dist/service-catalog/sc-record-producer-plugin.js +0 -2
- package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -1
- package/dist/service-catalog/variable-set-plugin.js +0 -2
- package/dist/service-catalog/variable-set-plugin.js.map +1 -1
- package/dist/service-portal/angular-provider-plugin.js +0 -2
- package/dist/service-portal/angular-provider-plugin.js.map +1 -1
- package/dist/service-portal/dependency-plugin.js +3 -5
- package/dist/service-portal/dependency-plugin.js.map +1 -1
- package/dist/service-portal/header-footer-plugin.js +3 -5
- package/dist/service-portal/header-footer-plugin.js.map +1 -1
- package/dist/service-portal/menu-plugin.js +0 -1
- package/dist/service-portal/menu-plugin.js.map +1 -1
- package/dist/service-portal/page-plugin.js +0 -1
- package/dist/service-portal/page-plugin.js.map +1 -1
- package/dist/service-portal/page-route-map-plugin.js +0 -1
- package/dist/service-portal/page-route-map-plugin.js.map +1 -1
- package/dist/service-portal/portal-plugin.js +0 -2
- package/dist/service-portal/portal-plugin.js.map +1 -1
- package/dist/service-portal/theme-plugin.js +0 -2
- package/dist/service-portal/theme-plugin.js.map +1 -1
- package/dist/service-portal/widget-plugin.js +3 -5
- package/dist/service-portal/widget-plugin.js.map +1 -1
- package/dist/sla-plugin.js +0 -2
- package/dist/sla-plugin.js.map +1 -1
- package/dist/static-content-plugin.js +32 -3
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +102 -11
- package/dist/table-plugin.js.map +1 -1
- package/dist/ui-action-plugin.js +26 -17
- package/dist/ui-action-plugin.js.map +1 -1
- package/dist/ui-page-plugin.js +159 -17
- package/dist/ui-page-plugin.js.map +1 -1
- package/dist/ui-policy-plugin.js +0 -1
- package/dist/ui-policy-plugin.js.map +1 -1
- package/dist/user-preference-plugin.js +0 -2
- package/dist/user-preference-plugin.js.map +1 -1
- package/dist/utils.d.ts +1 -9
- package/dist/utils.js +0 -14
- package/dist/utils.js.map +1 -1
- package/dist/ux-list-menu-config-plugin.js +0 -2
- package/dist/ux-list-menu-config-plugin.js.map +1 -1
- package/dist/view-plugin.js +0 -1
- package/dist/view-plugin.js.map +1 -1
- package/dist/workspace-plugin.js +0 -2
- package/dist/workspace-plugin.js.map +1 -1
- package/package.json +6 -6
- package/src/acl-plugin.ts +1 -4
- package/src/applicability-plugin.ts +0 -2
- package/src/application-menu-plugin.ts +0 -2
- package/src/arrow-function-plugin.ts +0 -1
- package/src/atf/test-plugin.ts +0 -2
- package/src/basic-syntax-plugin.ts +0 -1
- package/src/business-rule-plugin.ts +1 -2
- package/src/call-expression-plugin.ts +0 -1
- package/src/claims-plugin.ts +0 -1
- package/src/client-script-plugin.ts +1 -2
- package/src/column-plugin.ts +29 -9
- package/src/cross-scope-privilege-plugin.ts +1 -2
- package/src/dashboard/dashboard-plugin.ts +0 -2
- package/src/data-plugin.ts +0 -1
- package/src/data-policy-plugin.ts +333 -0
- package/src/email-notification-plugin.ts +8 -4
- package/src/flow/flow-logic/flow-logic-constants.ts +6 -0
- package/src/flow/flow-logic/flow-logic-diagnostics.ts +236 -58
- package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +59 -6
- package/src/flow/flow-logic/flow-logic-plugin.ts +368 -38
- package/src/flow/flow-logic/flow-logic-shapes.ts +25 -0
- package/src/flow/plugins/approval-rules-plugin.ts +0 -1
- package/src/flow/plugins/flow-action-definition-plugin.ts +940 -208
- package/src/flow/plugins/flow-data-pill-plugin.ts +3 -5
- package/src/flow/plugins/flow-definition-plugin.ts +159 -26
- package/src/flow/plugins/flow-diagnostics-plugin.ts +89 -3
- package/src/flow/plugins/flow-instance-plugin.ts +26 -12
- package/src/flow/plugins/flow-trigger-instance-plugin.ts +0 -1
- package/src/flow/plugins/inline-script-plugin.ts +0 -1
- package/src/flow/plugins/step-definition-plugin.ts +0 -2
- package/src/flow/plugins/step-instance-plugin.ts +259 -65
- package/src/flow/plugins/trigger-plugin.ts +0 -2
- package/src/flow/plugins/wfa-datapill-plugin.ts +0 -1
- package/src/flow/utils/datapill-transformer.ts +13 -5
- package/src/flow/utils/flow-constants.ts +19 -1
- package/src/flow/utils/flow-io-to-record.ts +29 -19
- package/src/flow/utils/flow-pill-utils.ts +48 -0
- package/src/flow/utils/flow-stage-processor.ts +831 -0
- package/src/flow/utils/pill-string-parser.ts +29 -47
- package/src/flow/utils/utils.ts +39 -35
- package/src/form-plugin.ts +5 -15
- package/src/html-import-plugin.ts +0 -1
- package/src/import-sets-plugin.ts +0 -2
- package/src/inbound-email-action-plugin.ts +1 -2
- package/src/index.ts +7 -1
- package/src/instance-scan-plugin.ts +0 -7
- package/src/json-plugin.ts +0 -1
- package/src/list-plugin.ts +6 -2
- package/src/now-attach-plugin.ts +0 -1
- package/src/now-config-plugin.ts +0 -1
- package/src/now-id-plugin.ts +0 -1
- package/src/now-include-plugin.ts +0 -1
- package/src/now-ref-plugin.ts +0 -1
- package/src/now-unresolved-plugin.ts +0 -1
- package/src/package-json-plugin.ts +8 -3
- package/src/property-plugin.ts +0 -2
- package/src/record-plugin.ts +3 -3
- package/src/repack/lint/Rules.ts +1 -1
- package/src/rest-api-plugin.ts +7 -6
- package/src/role-plugin.ts +1 -2
- package/src/schedule-script/scheduled-script-plugin.ts +11 -5
- package/src/script-action-plugin.ts +0 -2
- package/src/script-include-plugin.ts +0 -4
- package/src/server-module-plugin/index.ts +2 -3
- package/src/service-catalog/catalog-clientscript-plugin.ts +0 -2
- package/src/service-catalog/catalog-item-plugin.ts +0 -2
- package/src/service-catalog/catalog-ui-policy-plugin.ts +0 -2
- package/src/service-catalog/sc-record-producer-plugin.ts +0 -2
- package/src/service-catalog/variable-set-plugin.ts +0 -2
- package/src/service-portal/angular-provider-plugin.ts +0 -2
- package/src/service-portal/dependency-plugin.ts +0 -2
- package/src/service-portal/header-footer-plugin.ts +0 -2
- package/src/service-portal/menu-plugin.ts +1 -2
- package/src/service-portal/page-plugin.ts +1 -2
- package/src/service-portal/page-route-map-plugin.ts +1 -2
- package/src/service-portal/portal-plugin.ts +0 -2
- package/src/service-portal/theme-plugin.ts +0 -2
- package/src/service-portal/widget-plugin.ts +0 -2
- package/src/sla-plugin.ts +0 -2
- package/src/static-content-plugin.ts +37 -4
- package/src/table-plugin.ts +118 -16
- package/src/ui-action-plugin.ts +30 -17
- package/src/ui-page-plugin.ts +188 -20
- package/src/ui-policy-plugin.ts +1 -2
- package/src/user-preference-plugin.ts +0 -2
- package/src/utils.ts +0 -15
- package/src/ux-list-menu-config-plugin.ts +0 -2
- package/src/view-plugin.ts +0 -1
- package/src/workspace-plugin.ts +0 -2
package/src/ui-page-plugin.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
isSNScope,
|
|
9
9
|
zipSync,
|
|
10
10
|
unzipSync,
|
|
11
|
+
ts,
|
|
11
12
|
type Logger,
|
|
12
13
|
type Diagnostics,
|
|
13
14
|
type Project,
|
|
@@ -21,9 +22,10 @@ import { parseDocument, DomUtils } from 'htmlparser2'
|
|
|
21
22
|
import { XMLParser, XMLBuilder, type X2jOptions, type XmlBuilderOptions } from 'fast-xml-parser'
|
|
22
23
|
import { create } from 'xmlbuilder2'
|
|
23
24
|
import { NowIdShape } from './now-id-plugin'
|
|
25
|
+
import { NowIncludeShape } from './now-include-plugin'
|
|
24
26
|
import { CHUNK_SIZE, chunkData, generateId } from './static-content-plugin'
|
|
25
27
|
import { sha256 } from './now-attach-plugin'
|
|
26
|
-
import {
|
|
28
|
+
import { TRANSLATIONS_SUFFIX } from '@servicenow/isomorphic-rollup'
|
|
27
29
|
|
|
28
30
|
const parserOptions: X2jOptions = {
|
|
29
31
|
ignoreAttributes: false,
|
|
@@ -157,6 +159,50 @@ const SOURCE_ARTIFACT_RELATIONSHIPS = {
|
|
|
157
159
|
|
|
158
160
|
const parser = new XMLParser(parserOptions)
|
|
159
161
|
|
|
162
|
+
const escapeHtml = (s: string): string => s.replace(/&/g, '&')
|
|
163
|
+
|
|
164
|
+
const escapeSingle = (s: string): string => escapeHtml(s).replace(/\\/g, '\\\\').replace(/'/g, "\\'")
|
|
165
|
+
|
|
166
|
+
const escapeDouble = (s: string): string => escapeHtml(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
|
|
167
|
+
|
|
168
|
+
const getTranslationMessages = (
|
|
169
|
+
fs: FileSystem,
|
|
170
|
+
config: NowConfig,
|
|
171
|
+
rootDir: string,
|
|
172
|
+
htmlRelPathFromClientDir: string
|
|
173
|
+
): string[] => {
|
|
174
|
+
// The rollup plugin emits `<stem>.translations.json` next to each bundled html, preserving
|
|
175
|
+
// the html's subdirectory structure under clientDir. So a source html at
|
|
176
|
+
// `<clientDir>/admin/page.html` produces `<staticContentDir>/admin/page.translations.json`.
|
|
177
|
+
if (htmlRelPathFromClientDir.startsWith('..')) {
|
|
178
|
+
return []
|
|
179
|
+
}
|
|
180
|
+
const translationsRelPath = htmlRelPathFromClientDir.replace(/\.html$/, TRANSLATIONS_SUFFIX)
|
|
181
|
+
const translationsPath = path.join(rootDir, config.staticContentDir, translationsRelPath)
|
|
182
|
+
try {
|
|
183
|
+
fs.accessSync(translationsPath)
|
|
184
|
+
} catch {
|
|
185
|
+
return []
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const content = fs.readFileSync(translationsPath, { encoding: 'utf-8' })
|
|
189
|
+
const parsed = JSON.parse(content) as { messages: Array<string | { [key: string]: string }> }
|
|
190
|
+
return parsed.messages.map((entry) => (typeof entry === 'string' ? entry : (entry['code'] ?? '')))
|
|
191
|
+
} catch {
|
|
192
|
+
return []
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const translationsJellyScript = (scope: string, messages: string[]): string => `
|
|
197
|
+
<script type="text/javascript">
|
|
198
|
+
'use strict';
|
|
199
|
+
|
|
200
|
+
window.__TRANSLATIONS__ = {
|
|
201
|
+
${messages.map((message) => `'${escapeSingle(message)}': '\${NS,JS:sn_i18n.Message.getMessage("${escapeDouble(scope)}", "${escapeDouble(message)}")}'`).join(',\n ')}
|
|
202
|
+
};
|
|
203
|
+
</script>
|
|
204
|
+
`
|
|
205
|
+
|
|
160
206
|
// TODO: Remove this shim tag once we've shipped Glide support for this feature.
|
|
161
207
|
const nowUxGlobals = (themeId: string = POLARIS_APPSHELL_THEME_ID) => {
|
|
162
208
|
return parser.parse(`<!-- @sdk:now-ux-globals -->
|
|
@@ -216,7 +262,6 @@ const nodeTransformer = (nodes: any[]) => {
|
|
|
216
262
|
|
|
217
263
|
export const UiPagePlugin = Plugin.create({
|
|
218
264
|
name: 'UiPagePlugin',
|
|
219
|
-
docs: [createSdkDocEntry('UiPage', ['sys_ui_page'])],
|
|
220
265
|
records: {
|
|
221
266
|
sys_ui_page: {
|
|
222
267
|
composite: true,
|
|
@@ -271,7 +316,7 @@ export const UiPagePlugin = Plugin.create({
|
|
|
271
316
|
}
|
|
272
317
|
},
|
|
273
318
|
|
|
274
|
-
async toFile(uiPage, { config, descendants, transform }) {
|
|
319
|
+
async toFile(uiPage, { config, database, descendants, transform }) {
|
|
275
320
|
if (!uiPage.has('endpoint') && !uiPage.has('name')) {
|
|
276
321
|
return { success: false }
|
|
277
322
|
}
|
|
@@ -296,6 +341,7 @@ export const UiPagePlugin = Plugin.create({
|
|
|
296
341
|
|
|
297
342
|
const result = await serializeWithArtifact(uiPage, uiPagePropsToSerialize, {
|
|
298
343
|
config,
|
|
344
|
+
database,
|
|
299
345
|
descendants,
|
|
300
346
|
transform,
|
|
301
347
|
})
|
|
@@ -410,9 +456,29 @@ export const UiPagePlugin = Plugin.create({
|
|
|
410
456
|
diagnostics.error(endpoint.getOriginalNode(), 'endpoint must include a page name before .do')
|
|
411
457
|
return { success: false }
|
|
412
458
|
}
|
|
413
|
-
|
|
459
|
+
const htmlShape = arg.get('html')
|
|
460
|
+
let html = htmlShape.toString().getValue()
|
|
414
461
|
let sourceFilePaths: string[] = []
|
|
415
462
|
let assetNames: string[] = []
|
|
463
|
+
let vendorAssetNames: string[] = []
|
|
464
|
+
let htmlRelPathFromClientDir: string | undefined
|
|
465
|
+
|
|
466
|
+
const clientAbsDir = path.join(project.getRootDir(), config.clientDir)
|
|
467
|
+
const computeRelFromClientDir = (htmlIncludePath: string): string => {
|
|
468
|
+
const sourceFileDir = path.dirname(callExpression.getOriginalNode().getSourceFile().getFilePath())
|
|
469
|
+
const absoluteHtmlPath = path.resolve(sourceFileDir, htmlIncludePath)
|
|
470
|
+
return path.relative(clientAbsDir, absoluteHtmlPath).replace(/\\/g, '/')
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// `html: Now.include('../ui/hello.html')` resolves to a NowIncludeShape whose path
|
|
474
|
+
// we can read directly. The included content has no HTML_IMPORT_PREFIX, so detect
|
|
475
|
+
// this case before the prefix check below.
|
|
476
|
+
if (htmlShape.is(NowIncludeShape)) {
|
|
477
|
+
const includePath = htmlShape.as(NowIncludeShape).getPath()
|
|
478
|
+
if (includePath.endsWith('.html')) {
|
|
479
|
+
htmlRelPathFromClientDir = computeRelFromClientDir(includePath)
|
|
480
|
+
}
|
|
481
|
+
}
|
|
416
482
|
|
|
417
483
|
// HtmlImportPlugin (which runs before toRecord) resolves `html: _html` identifiers
|
|
418
484
|
// to the file content and prepends an HTML_IMPORT_PREFIX warning comment.
|
|
@@ -421,16 +487,23 @@ export const UiPagePlugin = Plugin.create({
|
|
|
421
487
|
// An inline string (e.g. `html: '<h1>...</h1>'`) never gets the prefix, so an
|
|
422
488
|
// unrelated `.html` import in the same file does NOT trigger artifact creation.
|
|
423
489
|
if (html.trimStart().startsWith(HTML_IMPORT_PREFIX)) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
//
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
490
|
+
// Resolve the import declaration from the specific identifier passed as the
|
|
491
|
+
// `html` argument — NOT the first .html import in the file. A single .now.ts
|
|
492
|
+
// may declare several UiPages with different html imports, and each one must
|
|
493
|
+
// pick up only the manifest/translations for the file it actually imports.
|
|
494
|
+
const htmlNode = htmlShape.getOriginalNode()
|
|
495
|
+
const moduleSpecifier = ts.Node.isIdentifier(htmlNode)
|
|
496
|
+
? htmlNode
|
|
497
|
+
.getSymbol()
|
|
498
|
+
?.getDeclarations()[0]
|
|
499
|
+
?.getParent()
|
|
500
|
+
?.asKind(ts.SyntaxKind.ImportDeclaration)
|
|
501
|
+
?.getModuleSpecifierValue()
|
|
502
|
+
: undefined
|
|
503
|
+
if (moduleSpecifier?.endsWith('.html')) {
|
|
504
|
+
htmlRelPathFromClientDir = computeRelFromClientDir(moduleSpecifier)
|
|
505
|
+
const sourceFileDir = path.dirname(htmlNode.getSourceFile().getFilePath())
|
|
506
|
+
const absoluteHtmlPath = path.resolve(sourceFileDir, moduleSpecifier)
|
|
434
507
|
const manifest = getUIPageSourceFilePaths(
|
|
435
508
|
absoluteHtmlPath,
|
|
436
509
|
fs,
|
|
@@ -440,6 +513,7 @@ export const UiPagePlugin = Plugin.create({
|
|
|
440
513
|
)
|
|
441
514
|
sourceFilePaths = manifest.files
|
|
442
515
|
assetNames = manifest.assetNames
|
|
516
|
+
vendorAssetNames = manifest.vendorAssetNames
|
|
443
517
|
}
|
|
444
518
|
}
|
|
445
519
|
|
|
@@ -458,6 +532,17 @@ export const UiPagePlugin = Plugin.create({
|
|
|
458
532
|
}
|
|
459
533
|
return { success: false }
|
|
460
534
|
}
|
|
535
|
+
if (htmlRelPathFromClientDir) {
|
|
536
|
+
const messages = getTranslationMessages(
|
|
537
|
+
fs,
|
|
538
|
+
config,
|
|
539
|
+
project.getRootDir(),
|
|
540
|
+
htmlRelPathFromClientDir
|
|
541
|
+
)
|
|
542
|
+
if (messages.length > 0) {
|
|
543
|
+
html += translationsJellyScript(config.scope, messages)
|
|
544
|
+
}
|
|
545
|
+
}
|
|
461
546
|
}
|
|
462
547
|
|
|
463
548
|
const record = await factory.createRecord({
|
|
@@ -503,6 +588,28 @@ export const UiPagePlugin = Plugin.create({
|
|
|
503
588
|
assetNames
|
|
504
589
|
)
|
|
505
590
|
|
|
591
|
+
// Link this page's source artifact to each vendor chunk it depends on.
|
|
592
|
+
// Emitted for both configuration and package builds: configuration
|
|
593
|
+
// deploys need the M2Ms so the platform knows which vendor chunks belong
|
|
594
|
+
// to this page; package builds need them so vendor refs are tracked in
|
|
595
|
+
// keys.ts and not flagged as deletes on the next sync.
|
|
596
|
+
if (vendorAssetNames.length > 0) {
|
|
597
|
+
const artifactRecord = sourceArtifactRecords.find(
|
|
598
|
+
(r) => r.getTable() === 'sn_glider_source_artifact'
|
|
599
|
+
)
|
|
600
|
+
if (artifactRecord) {
|
|
601
|
+
const vendorM2ms = await Promise.all(
|
|
602
|
+
vendorAssetNames.map((name) =>
|
|
603
|
+
createAssetArtifactM2mRecord(artifactRecord, name, record, {
|
|
604
|
+
factory,
|
|
605
|
+
config,
|
|
606
|
+
})
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
sourceArtifactRecords.push(...vendorM2ms)
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
506
613
|
if (sourceArtifactRecords.length > 0) {
|
|
507
614
|
record.with(...sourceArtifactRecords)
|
|
508
615
|
} else {
|
|
@@ -523,17 +630,18 @@ export const UiPagePlugin = Plugin.create({
|
|
|
523
630
|
})
|
|
524
631
|
|
|
525
632
|
/**
|
|
526
|
-
* Reads source file paths from the UI source manifest file.
|
|
633
|
+
* Reads source file paths and vendor asset names from the UI source manifest file.
|
|
527
634
|
*
|
|
528
635
|
* The manifest is generated by isomorphic-rollup's sourceManifest plugin during build.
|
|
529
|
-
* It's a JSON file with the structure:
|
|
636
|
+
* It's a JSON file with the structure:
|
|
637
|
+
* { html, entry, files: string[], vendors: [fileName, contentHash][] }
|
|
530
638
|
*
|
|
531
639
|
* @param htmlFilePath - Path to the HTML file
|
|
532
640
|
* @param fs - File system interface
|
|
533
641
|
* @param logger - Logger for diagnostics
|
|
534
642
|
* @param config - NowConfig with staticContentDir
|
|
535
643
|
* @param rootDir - Project root directory
|
|
536
|
-
* @returns
|
|
644
|
+
* @returns Source file paths, entry asset names, and vendor asset names
|
|
537
645
|
*/
|
|
538
646
|
const getUIPageSourceFilePaths = (
|
|
539
647
|
htmlFilePath: string,
|
|
@@ -541,8 +649,8 @@ const getUIPageSourceFilePaths = (
|
|
|
541
649
|
logger: Logger,
|
|
542
650
|
config: NowConfig,
|
|
543
651
|
rootDir: string
|
|
544
|
-
): { files: string[]; assetNames: string[] } => {
|
|
545
|
-
const empty = { files: [], assetNames: [] }
|
|
652
|
+
): { files: string[]; assetNames: string[]; vendorAssetNames: string[] } => {
|
|
653
|
+
const empty = { files: [], assetNames: [], vendorAssetNames: [] }
|
|
546
654
|
try {
|
|
547
655
|
// Derive manifest path from HTML path by mirroring the directory structure
|
|
548
656
|
// from clientDir into staticContentDir and swapping the extension.
|
|
@@ -596,7 +704,30 @@ const getUIPageSourceFilePaths = (
|
|
|
596
704
|
// no source map in this build output — skip
|
|
597
705
|
}
|
|
598
706
|
|
|
599
|
-
|
|
707
|
+
// Derive vendor asset names from the manifest's vendors field.
|
|
708
|
+
// Each vendor entry is [fileName, contentHash], e.g.
|
|
709
|
+
// ["vendor-react-dom--d217b640.jsdbx", "d217b640"]
|
|
710
|
+
// The asset name mirrors static-content-plugin's formula:
|
|
711
|
+
// path.join(scope, fileNameWithoutExt)
|
|
712
|
+
const vendorAssetNames: string[] = []
|
|
713
|
+
const vendors: [string, string][] = manifest.vendors ?? []
|
|
714
|
+
for (const [fileName] of vendors) {
|
|
715
|
+
const ext = path.extname(fileName)
|
|
716
|
+
const nameWithoutExt = fileName.substring(0, fileName.length - ext.length)
|
|
717
|
+
const vendorAssetName = path.join(config.scope, nameWithoutExt).replace(/\\/g, '/')
|
|
718
|
+
vendorAssetNames.push(vendorAssetName)
|
|
719
|
+
|
|
720
|
+
// Check for vendor sourcemap
|
|
721
|
+
const vendorMapPath = path.join(staticContentAbsDir, `${nameWithoutExt}.jsdbx.map`)
|
|
722
|
+
try {
|
|
723
|
+
fs.accessSync(vendorMapPath)
|
|
724
|
+
vendorAssetNames.push(path.join(config.scope, `${nameWithoutExt}.js.map`).replace(/\\/g, '/'))
|
|
725
|
+
} catch {
|
|
726
|
+
// no sourcemap for this vendor chunk
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
return { files: manifest.files, assetNames, vendorAssetNames }
|
|
600
731
|
} catch (error) {
|
|
601
732
|
logger.warn(`Failed to read source manifest: ${error}`)
|
|
602
733
|
return empty
|
|
@@ -1114,6 +1245,7 @@ async function serializeWithArtifact(
|
|
|
1114
1245
|
metadataRecord: Record,
|
|
1115
1246
|
metadataProps: string[],
|
|
1116
1247
|
context: {
|
|
1248
|
+
database: Database
|
|
1117
1249
|
descendants: { query: (table: string) => Record[] }
|
|
1118
1250
|
config: { scope: string; scopeId: string }
|
|
1119
1251
|
transform: Transform
|
|
@@ -1293,6 +1425,42 @@ async function serializeWithArtifact(
|
|
|
1293
1425
|
? `sys_attachment.table_sys_id=${artifactId}^sys_idNOT IN${currentDocIds.join(',')}`
|
|
1294
1426
|
: `sys_attachment.table_sys_id=${artifactId}`
|
|
1295
1427
|
recordUpdate.ele('sys_attachment_doc', { action: 'delete_multiple', query: docQuery })
|
|
1428
|
+
|
|
1429
|
+
// Clean up stale source-artifact M2Ms for this artifact (e.g. when a vendor
|
|
1430
|
+
// chunk hash changes, the M2M to the prior vendor asset must be removed).
|
|
1431
|
+
//
|
|
1432
|
+
// Query the full database, not page descendants: asset M2Ms are descendants
|
|
1433
|
+
// of their sys_ux_lib_asset records, not of the page, so the page's
|
|
1434
|
+
// descendants only have the page M2M. The NOT IN list must include every
|
|
1435
|
+
// current-build M2M for this artifact, otherwise the sweep would also
|
|
1436
|
+
// delete live entry/vendor M2Ms inserted by the asset XMLs.
|
|
1437
|
+
//
|
|
1438
|
+
// Skip DELETE-action rows: on a same-project package rebuild,
|
|
1439
|
+
// generateRecordsFromDeletedKeys inserts DELETE rows for keys no longer
|
|
1440
|
+
// registered (e.g. the prior vendor M2M). Adding their sys_ids to NOT IN
|
|
1441
|
+
// would protect the stale rows on the platform — defeating the sweep.
|
|
1442
|
+
const currentM2mIds = context.database
|
|
1443
|
+
.query('sn_glider_source_artifact_m2m')
|
|
1444
|
+
.filter((m2m) => {
|
|
1445
|
+
if (m2m.isDeleted()) {
|
|
1446
|
+
return false
|
|
1447
|
+
}
|
|
1448
|
+
const srcArtifact = m2m.get('source_artifact')
|
|
1449
|
+
const srcId = srcArtifact.isRecord()
|
|
1450
|
+
? srcArtifact.asRecord().getId().getValue()
|
|
1451
|
+
: srcArtifact.toString().getValue()
|
|
1452
|
+
return srcId === artifactId
|
|
1453
|
+
})
|
|
1454
|
+
.map((m2m) => m2m.getId().getValue())
|
|
1455
|
+
|
|
1456
|
+
const m2mQuery =
|
|
1457
|
+
currentM2mIds.length > 0
|
|
1458
|
+
? `source_artifact=${artifactId}^sys_idNOT IN${currentM2mIds.join(',')}`
|
|
1459
|
+
: `source_artifact=${artifactId}`
|
|
1460
|
+
recordUpdate.ele('sn_glider_source_artifact_m2m', {
|
|
1461
|
+
action: 'delete_multiple',
|
|
1462
|
+
query: m2mQuery,
|
|
1463
|
+
})
|
|
1296
1464
|
})
|
|
1297
1465
|
|
|
1298
1466
|
return {
|
package/src/ui-policy-plugin.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type Record,
|
|
9
9
|
type Shape,
|
|
10
10
|
} from '@servicenow/sdk-build-core'
|
|
11
|
-
import {
|
|
11
|
+
import { validateClientSideScript } from './utils'
|
|
12
12
|
import { NowIdShape } from './now-id-plugin'
|
|
13
13
|
|
|
14
14
|
// Define table names as constants since they're not exported from the core tables
|
|
@@ -93,7 +93,6 @@ const validateScriptProperty = (
|
|
|
93
93
|
|
|
94
94
|
export const UiPolicyPlugin = Plugin.create({
|
|
95
95
|
name: 'UiPolicyPlugin',
|
|
96
|
-
docs: [createSdkDocEntry('UiPolicy', ['sys_ui_policy'])],
|
|
97
96
|
records: {
|
|
98
97
|
[SYS_UI_POLICY]: {
|
|
99
98
|
coalesce: ['table', 'short_description'],
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core'
|
|
2
2
|
import { NowIdShape } from './now-id-plugin'
|
|
3
|
-
import { createSdkDocEntry } from './utils'
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Creates a User Preference (sys_user_preference).
|
|
@@ -17,7 +16,6 @@ import { createSdkDocEntry } from './utils'
|
|
|
17
16
|
*/
|
|
18
17
|
export const UserPreferencePlugin = Plugin.create({
|
|
19
18
|
name: 'UserPreferencePlugin',
|
|
20
|
-
docs: [createSdkDocEntry('UserPreference', ['sys_user_preference'])],
|
|
21
19
|
records: {
|
|
22
20
|
sys_user_preference: {
|
|
23
21
|
toShape(record) {
|
package/src/utils.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
type ObjectShape,
|
|
5
5
|
type Diagnostics,
|
|
6
6
|
type Compiler,
|
|
7
|
-
type PluginApiDoc,
|
|
8
7
|
type Record as FluentRecord,
|
|
9
8
|
type OutputFile,
|
|
10
9
|
type Transform,
|
|
@@ -182,20 +181,6 @@ export async function generateChoiceSetFile(
|
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
183
|
|
|
185
|
-
/**
|
|
186
|
-
* Creates a documentation entry for first-party SDK plugins.
|
|
187
|
-
*
|
|
188
|
-
* @param apiName - The API name (e.g., 'BusinessRule', 'Acl')
|
|
189
|
-
* @param tags - Keywords for categorization (typically includes the ServiceNow table name)
|
|
190
|
-
* @returns A complete PluginApiDoc entry
|
|
191
|
-
*/
|
|
192
|
-
export function createSdkDocEntry(apiName: string, tags: string[]): PluginApiDoc {
|
|
193
|
-
return {
|
|
194
|
-
apiName,
|
|
195
|
-
tags,
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
184
|
/**
|
|
200
185
|
* Parses a number from a shape record field with fallback to default value.
|
|
201
186
|
* Returns undefined if the field doesn't exist and no default is provided.
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { Plugin, CallExpressionShape, type Record } from '@servicenow/sdk-build-core'
|
|
2
2
|
|
|
3
3
|
import { NowIdShape } from './now-id-plugin'
|
|
4
|
-
import { createSdkDocEntry } from './utils'
|
|
5
4
|
|
|
6
5
|
export const UxListMenuConfigPlugin = Plugin.create({
|
|
7
6
|
name: 'UxListMenuConfigPlugin',
|
|
8
|
-
docs: [createSdkDocEntry('UxListMenuConfig', ['sys_ux_list_menu_config'])],
|
|
9
7
|
records: {
|
|
10
8
|
sys_ux_list_menu_config: {
|
|
11
9
|
relationships: {
|
package/src/view-plugin.ts
CHANGED
package/src/workspace-plugin.ts
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
Database,
|
|
9
9
|
} from '@servicenow/sdk-build-core'
|
|
10
10
|
import { NowIdShape } from './now-id-plugin'
|
|
11
|
-
import { createSdkDocEntry } from './utils'
|
|
12
11
|
import { parsePagePropChromeTabJson, createChromeTabJsonStringForPageProp } from './workspace-plugin/chrome-tab'
|
|
13
12
|
import { createPage } from './workspace-plugin/page'
|
|
14
13
|
import {
|
|
@@ -43,7 +42,6 @@ type InnerTransformFromObjectShape = Parameters<Parameters<ObjectShape['transfor
|
|
|
43
42
|
|
|
44
43
|
export const WorkspacePlugin = Plugin.create({
|
|
45
44
|
name: 'WorkspacePlugin',
|
|
46
|
-
docs: [createSdkDocEntry('Workspace', ['sys_ux_page_registry'])],
|
|
47
45
|
records: {
|
|
48
46
|
sys_ux_page_registry: {
|
|
49
47
|
relationships: {
|