@servicenow/sdk-build-plugins 4.0.2 → 4.1.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.
- package/dist/acl-plugin.js +23 -16
- package/dist/acl-plugin.js.map +1 -1
- package/dist/application-menu-plugin.js +15 -14
- package/dist/application-menu-plugin.js.map +1 -1
- package/dist/atf/test-plugin.js +37 -34
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +50 -1
- package/dist/basic-syntax-plugin.js.map +1 -1
- package/dist/business-rule-plugin.js +12 -10
- package/dist/business-rule-plugin.js.map +1 -1
- package/dist/claims-plugin.d.ts +3 -0
- package/dist/claims-plugin.js +95 -0
- package/dist/claims-plugin.js.map +1 -0
- package/dist/client-script-plugin.js +1 -1
- package/dist/client-script-plugin.js.map +1 -1
- package/dist/column/column-to-record.d.ts +3 -3
- package/dist/column/column-to-record.js +17 -16
- package/dist/column/column-to-record.js.map +1 -1
- package/dist/column-plugin.js +86 -8
- package/dist/column-plugin.js.map +1 -1
- package/dist/cross-scope-privilege-plugin.js +17 -3
- package/dist/cross-scope-privilege-plugin.js.map +1 -1
- package/dist/html-import-plugin.js +8 -1
- package/dist/html-import-plugin.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/json-plugin.d.ts +7 -2
- package/dist/json-plugin.js +28 -12
- package/dist/json-plugin.js.map +1 -1
- package/dist/list-plugin.js +29 -17
- package/dist/list-plugin.js.map +1 -1
- package/dist/now-config-plugin.js +14 -5
- package/dist/now-config-plugin.js.map +1 -1
- package/dist/now-include-plugin.d.ts +6 -7
- package/dist/now-include-plugin.js +59 -26
- package/dist/now-include-plugin.js.map +1 -1
- package/dist/now-ref-plugin.js +1 -1
- package/dist/now-ref-plugin.js.map +1 -1
- package/dist/package-json-plugin.js +5 -7
- package/dist/package-json-plugin.js.map +1 -1
- package/dist/property-plugin.js +1 -1
- package/dist/property-plugin.js.map +1 -1
- package/dist/record-plugin.js +23 -9
- package/dist/record-plugin.js.map +1 -1
- package/dist/repack/index.d.ts +2 -0
- package/dist/repack/index.js +8 -0
- package/dist/repack/index.js.map +1 -1
- package/dist/rest-api-plugin.js +12 -12
- package/dist/rest-api-plugin.js.map +1 -1
- package/dist/role-plugin.js +18 -16
- package/dist/role-plugin.js.map +1 -1
- package/dist/script-action-plugin.js +1 -1
- package/dist/script-action-plugin.js.map +1 -1
- package/dist/script-include-plugin.js +6 -4
- package/dist/script-include-plugin.js.map +1 -1
- package/dist/server-module-plugin/index.d.ts +3 -1
- package/dist/server-module-plugin/index.js +110 -28
- package/dist/server-module-plugin/index.js.map +1 -1
- package/dist/service-portal/angular-provider-plugin.js +3 -3
- package/dist/service-portal/angular-provider-plugin.js.map +1 -1
- package/dist/service-portal/dependency-plugin.js +9 -12
- package/dist/service-portal/dependency-plugin.js.map +1 -1
- package/dist/service-portal/widget-plugin.js +8 -8
- package/dist/service-portal/widget-plugin.js.map +1 -1
- package/dist/static-content-plugin.d.ts +2 -0
- package/dist/static-content-plugin.js +16 -13
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +55 -33
- package/dist/table-plugin.js.map +1 -1
- package/dist/ui-action-plugin.js +29 -19
- package/dist/ui-action-plugin.js.map +1 -1
- package/dist/ui-page-plugin.js +6 -3
- package/dist/ui-page-plugin.js.map +1 -1
- package/dist/user-preference-plugin.js +2 -2
- package/dist/user-preference-plugin.js.map +1 -1
- package/package.json +5 -5
- package/src/acl-plugin.ts +31 -27
- package/src/application-menu-plugin.ts +39 -39
- package/src/atf/test-plugin.ts +82 -81
- package/src/basic-syntax-plugin.ts +54 -1
- package/src/business-rule-plugin.ts +74 -73
- package/src/claims-plugin.ts +116 -0
- package/src/client-script-plugin.ts +1 -1
- package/src/column/column-to-record.ts +59 -53
- package/src/column-plugin.ts +93 -8
- package/src/cross-scope-privilege-plugin.ts +18 -3
- package/src/html-import-plugin.ts +12 -2
- package/src/index.ts +2 -1
- package/src/json-plugin.ts +35 -15
- package/src/list-plugin.ts +39 -30
- package/src/now-config-plugin.ts +19 -8
- package/src/now-include-plugin.ts +64 -30
- package/src/now-ref-plugin.ts +1 -1
- package/src/package-json-plugin.ts +7 -6
- package/src/property-plugin.ts +1 -1
- package/src/record-plugin.ts +25 -9
- package/src/repack/index.ts +14 -0
- package/src/rest-api-plugin.ts +15 -15
- package/src/role-plugin.ts +15 -15
- package/src/script-action-plugin.ts +1 -1
- package/src/script-include-plugin.ts +7 -4
- package/src/server-module-plugin/index.ts +158 -43
- package/src/service-portal/angular-provider-plugin.ts +12 -10
- package/src/service-portal/dependency-plugin.ts +12 -13
- package/src/service-portal/widget-plugin.ts +36 -30
- package/src/static-content-plugin.ts +12 -10
- package/src/table-plugin.ts +71 -56
- package/src/ui-action-plugin.ts +49 -33
- package/src/ui-page-plugin.ts +6 -3
- package/src/user-preference-plugin.ts +2 -2
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Plugin, type Project, type NowConfig, type Record } from '@servicenow/sdk-build-core'
|
|
2
|
+
import { JsonFileShape } from './json-plugin'
|
|
3
|
+
export const CLAIMS_FILE = '.claims.json'
|
|
4
|
+
|
|
5
|
+
function getClaimsPath(project: Project, config: NowConfig): string {
|
|
6
|
+
return project.resolvePath(config.generatedDir, CLAIMS_FILE)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const ClaimsPlugin = Plugin.create({
|
|
10
|
+
name: 'ClaimsPlugin',
|
|
11
|
+
files: [
|
|
12
|
+
{
|
|
13
|
+
entryPoint: true,
|
|
14
|
+
matcher: (path, { project, config }) => path === getClaimsPath(project, config),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
records: {
|
|
18
|
+
sys_claim: {
|
|
19
|
+
coalesce: ['claim_owner_scope', 'previous_claim_scope', 'metadata_update_name'],
|
|
20
|
+
toFile() {
|
|
21
|
+
// Claims don't get their own file, they're appended to the corresponding record's payload
|
|
22
|
+
return { success: true, value: [] }
|
|
23
|
+
},
|
|
24
|
+
toShape(root, { descendants, database, project, config }) {
|
|
25
|
+
descendants.insert(...database.query('sys_claim')) // Adding them as descendants will mark them as handled so they don't get reprocessed
|
|
26
|
+
const unsorted: globalThis.Record<string, string[]> = {}
|
|
27
|
+
for (const claim of descendants) {
|
|
28
|
+
const updateName = claim.get('metadata_update_name').asString().getValue().trim()
|
|
29
|
+
const timestamp = claim.get('claim_timestamp').asString().getValue().trim()
|
|
30
|
+
const ownerScope = claim.get('claim_owner_scope').asString().getValue().trim()
|
|
31
|
+
const previousScope = claim.get('previous_claim_scope').asString().getValue().trim()
|
|
32
|
+
const previousVersion = claim.get('previous_claim_app_version').ifString()?.getValue().trim() ?? ''
|
|
33
|
+
|
|
34
|
+
const array = (unsorted[updateName] ??= [])
|
|
35
|
+
array.push(`${timestamp};${ownerScope};${previousScope};${previousVersion}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const sorted = Object.fromEntries(
|
|
39
|
+
Object.entries(unsorted).map(([updateName, claims]) => [updateName, claims.sort()])
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
value: new JsonFileShape({
|
|
45
|
+
source: root,
|
|
46
|
+
path: getClaimsPath(project, config),
|
|
47
|
+
content: JSON.stringify(sorted),
|
|
48
|
+
json: sorted,
|
|
49
|
+
}),
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
shapes: [
|
|
55
|
+
{
|
|
56
|
+
shape: JsonFileShape,
|
|
57
|
+
async toRecord(file, { project, config, factory }) {
|
|
58
|
+
if (file.getPath() !== getClaimsPath(project, config)) {
|
|
59
|
+
return { success: false }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const allClaims = file.getJson()
|
|
63
|
+
const records: Record[] = []
|
|
64
|
+
for (const [updateName, claims] of allClaims.entries()) {
|
|
65
|
+
for (const claim of claims
|
|
66
|
+
.asArray(
|
|
67
|
+
`Claims entry for ${updateName} is malformed. Expected array, but received: ${claims.getDescription()}`
|
|
68
|
+
)
|
|
69
|
+
.getElements()) {
|
|
70
|
+
const [timestamp, ownerScope, previousScope, previousVersion] = claim
|
|
71
|
+
.asString(
|
|
72
|
+
`Claim for ${updateName} is malformed. Expected string, but received: ${claim.getDescription()}`
|
|
73
|
+
)
|
|
74
|
+
.split(';')
|
|
75
|
+
.map((part) => part.trim())
|
|
76
|
+
|
|
77
|
+
if (!timestamp) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Claim for ${updateName} is malformed. Expected timestamp at first position.`
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!ownerScope) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Claim for ${updateName} is malformed. Expected owner scope at second position.`
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!previousScope) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Claim for ${updateName} is malformed. Expected previous scope at third position.`
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
records.push(
|
|
96
|
+
await factory.createRecord({
|
|
97
|
+
source: file,
|
|
98
|
+
table: 'sys_claim',
|
|
99
|
+
properties: {
|
|
100
|
+
metadata_update_name: updateName,
|
|
101
|
+
claim_timestamp: timestamp,
|
|
102
|
+
claim_owner_scope: ownerScope,
|
|
103
|
+
previous_claim_scope: previousScope,
|
|
104
|
+
previous_claim_app_version: previousVersion || undefined,
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const [first, ...rest] = records
|
|
112
|
+
return first ? { success: true, value: first.with(...rest) } : { success: false }
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
})
|
|
@@ -119,7 +119,7 @@ export const ClientScriptPlugin = Plugin.create({
|
|
|
119
119
|
|
|
120
120
|
return {
|
|
121
121
|
success: true,
|
|
122
|
-
value: factory.createRecord({
|
|
122
|
+
value: await factory.createRecord({
|
|
123
123
|
source: callExpression,
|
|
124
124
|
table: 'sys_script_client',
|
|
125
125
|
explicitId: clientScript.get('$id'),
|
|
@@ -3,12 +3,13 @@ import {
|
|
|
3
3
|
type CallExpressionShape,
|
|
4
4
|
type Diagnostics,
|
|
5
5
|
type Factory,
|
|
6
|
+
type Record,
|
|
6
7
|
StringShape,
|
|
7
8
|
} from '@servicenow/sdk-build-core'
|
|
8
9
|
import { generateDeprecatedDiagnostics } from '../utils'
|
|
9
10
|
import { generatePlural } from '../column-plugin'
|
|
10
11
|
|
|
11
|
-
export function getDocumentationRecords(
|
|
12
|
+
export async function getDocumentationRecords(
|
|
12
13
|
callExpression: CallExpressionShape,
|
|
13
14
|
aliasedKeys: globalThis.Record<string, string[]>,
|
|
14
15
|
factory: Factory,
|
|
@@ -20,7 +21,7 @@ export function getDocumentationRecords(
|
|
|
20
21
|
const columnName = column.get('name')
|
|
21
22
|
if (!documentation.if([ArrayShape, StringShape])) {
|
|
22
23
|
return [
|
|
23
|
-
factory.createRecord({
|
|
24
|
+
await factory.createRecord({
|
|
24
25
|
source: callExpression,
|
|
25
26
|
table: 'sys_documentation',
|
|
26
27
|
properties: column.transform(({ $ }) => ({
|
|
@@ -39,30 +40,30 @@ export function getDocumentationRecords(
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
if (documentation.ifArray()) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
43
|
+
const docRecords: Record[] = []
|
|
44
|
+
for (const doc of documentation.asArray().getElements()) {
|
|
45
|
+
const docObject = doc.asObject().withAliasedKeys(aliasedKeys)
|
|
46
|
+
generateDeprecatedDiagnostics(docObject, diagnostics)
|
|
47
|
+
docRecords.push(
|
|
48
|
+
await factory.createRecord({
|
|
49
|
+
source: callExpression,
|
|
50
|
+
table: 'sys_documentation',
|
|
51
|
+
properties: docObject.transform(({ $ }) => ({
|
|
52
|
+
name: $.val(column.get('table')),
|
|
53
|
+
element: $.val(column.get('name')),
|
|
54
|
+
language: $,
|
|
55
|
+
hint: $,
|
|
56
|
+
help: $,
|
|
57
|
+
label: $,
|
|
58
|
+
plural: $,
|
|
59
|
+
url: $,
|
|
60
|
+
url_target: $.from('urlTarget'),
|
|
61
|
+
})),
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return docRecords
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
if (!generateDefaultDoc) {
|
|
@@ -70,7 +71,7 @@ export function getDocumentationRecords(
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
return [
|
|
73
|
-
factory.createRecord({
|
|
74
|
+
await factory.createRecord({
|
|
74
75
|
source: callExpression,
|
|
75
76
|
table: 'sys_documentation',
|
|
76
77
|
properties: column.transform(({ $ }) => ({
|
|
@@ -86,7 +87,7 @@ export function getDocumentationRecords(
|
|
|
86
87
|
]
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
export function getChoiceRecords(
|
|
90
|
+
export async function getChoiceRecords(
|
|
90
91
|
callExpression: CallExpressionShape,
|
|
91
92
|
aliasedKeys: globalThis.Record<string, string[]>,
|
|
92
93
|
factory: Factory,
|
|
@@ -98,34 +99,39 @@ export function getChoiceRecords(
|
|
|
98
99
|
return []
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
|
|
102
|
+
const records: Record[] = []
|
|
103
|
+
for (const choiceValue of Object.keys(choiceArg.getValue())) {
|
|
102
104
|
// TODO Should have proper type here
|
|
103
105
|
const choice = choiceArg.get(choiceValue)
|
|
104
106
|
if (choice.isObject()) {
|
|
105
107
|
generateDeprecatedDiagnostics(choice.withAliasedKeys(aliasedKeys), diagnostics)
|
|
106
108
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
109
|
+
records.push(
|
|
110
|
+
await factory.createRecord({
|
|
111
|
+
source: callExpression,
|
|
112
|
+
table: 'sys_choice',
|
|
113
|
+
properties: choice.isString()
|
|
114
|
+
? {
|
|
115
|
+
name: column.get('table').asString().getValue(),
|
|
116
|
+
element: column.get('name').asString().getValue(),
|
|
117
|
+
label: choice,
|
|
118
|
+
value: choiceValue,
|
|
119
|
+
}
|
|
120
|
+
: choice.asObject().transform(({ $ }) => ({
|
|
121
|
+
name: $.val(column.get('table')),
|
|
122
|
+
element: $.val(column.get('name')),
|
|
123
|
+
label: $,
|
|
124
|
+
value: $.val(choiceValue),
|
|
125
|
+
sequence: $,
|
|
126
|
+
dependent_value: $.from('dependentValue'),
|
|
127
|
+
hint: $,
|
|
128
|
+
inactive: $.toBoolean().def(false),
|
|
129
|
+
inactive_on_update: $.from('inactiveOnUpdate').toBoolean().def(false),
|
|
130
|
+
language: $.def('en'),
|
|
131
|
+
})),
|
|
132
|
+
})
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return records
|
|
131
137
|
}
|
package/src/column-plugin.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from './column/column-helper'
|
|
11
11
|
import { ModuleFunctionShape } from './server-module-plugin'
|
|
12
12
|
import { generateDeprecatedDiagnostics } from './utils'
|
|
13
|
+
import { create } from 'xmlbuilder2'
|
|
13
14
|
|
|
14
15
|
const PLURAL_EQUALS_LABEL = [
|
|
15
16
|
's',
|
|
@@ -63,8 +64,80 @@ const documentationAliases = {
|
|
|
63
64
|
export const ColumnPlugin = Plugin.create({
|
|
64
65
|
name: 'ColumnPlugin',
|
|
65
66
|
records: {
|
|
66
|
-
sys_choice: {
|
|
67
|
-
|
|
67
|
+
sys_choice: {
|
|
68
|
+
coalesce: ['name', 'element', 'value'],
|
|
69
|
+
getUpdateName: (record) => ({
|
|
70
|
+
success: true,
|
|
71
|
+
value: `sys_choice_${record.get('name').getValue()}_${record.get('element').getValue()}`,
|
|
72
|
+
}),
|
|
73
|
+
},
|
|
74
|
+
sys_choice_set: {
|
|
75
|
+
coalesce: ['name', 'element'],
|
|
76
|
+
relationships: {
|
|
77
|
+
sys_choice: {
|
|
78
|
+
via: {
|
|
79
|
+
name: 'name',
|
|
80
|
+
element: 'element',
|
|
81
|
+
},
|
|
82
|
+
descendant: true,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
getUpdateName: (record) => ({
|
|
86
|
+
success: true,
|
|
87
|
+
// Seems odd, but according to UpdateName.java, sys_choice and sys_choice_set share the same update naming logic
|
|
88
|
+
value: `sys_choice_${record.get('name').getValue()}_${record.get('element').getValue()}`,
|
|
89
|
+
}),
|
|
90
|
+
async toFile(choiceSet, { config, descendants, transform }) {
|
|
91
|
+
if (config.tableOutputFormat === 'bootstrap') {
|
|
92
|
+
// Defer to table plugin
|
|
93
|
+
return { success: false }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const tableName = choiceSet.get('name').asString().getValue()
|
|
97
|
+
const elementName = choiceSet.get('element').asString().getValue()
|
|
98
|
+
const xml = create().ele('record_update')
|
|
99
|
+
const root = xml.ele('sys_choice_set', { table: tableName })
|
|
100
|
+
descendants.query('sys_choice').forEach((choice) => {
|
|
101
|
+
const child = root.ele('sys_choice', { action: choice.getAction() })
|
|
102
|
+
child.ele('sys_id').txt(choice.getId().getValue())
|
|
103
|
+
child.ele('name').txt(tableName)
|
|
104
|
+
child.ele('element').txt(elementName)
|
|
105
|
+
|
|
106
|
+
for (const prop of [
|
|
107
|
+
'label',
|
|
108
|
+
'value',
|
|
109
|
+
'sequence',
|
|
110
|
+
'dependent_value',
|
|
111
|
+
'hint',
|
|
112
|
+
'inactive',
|
|
113
|
+
'inactive_on_update',
|
|
114
|
+
'language',
|
|
115
|
+
]) {
|
|
116
|
+
choice
|
|
117
|
+
.get(prop)
|
|
118
|
+
.ifDefined()
|
|
119
|
+
?.toString()
|
|
120
|
+
.pipe((p) => child.ele(prop).txt(p.getValue()))
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const child = root.ele('sys_choice_set', { action: choiceSet.getAction() })
|
|
125
|
+
child.ele('sys_id').txt(choiceSet.getId().getValue())
|
|
126
|
+
child.ele('sys_scope', { display_value: config.scope }).txt(config.scopeId)
|
|
127
|
+
child.ele('name').txt(tableName)
|
|
128
|
+
child.ele('element').txt(elementName)
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
success: true,
|
|
132
|
+
value: {
|
|
133
|
+
source: choiceSet,
|
|
134
|
+
name: `${await transform.getUpdateName(choiceSet)}.xml`,
|
|
135
|
+
category: choiceSet.getInstallCategory(),
|
|
136
|
+
content: xml.end({ prettyPrint: true }),
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
},
|
|
68
141
|
},
|
|
69
142
|
shapes: [
|
|
70
143
|
{
|
|
@@ -82,20 +155,32 @@ export const ColumnPlugin = Plugin.create({
|
|
|
82
155
|
return { success: false }
|
|
83
156
|
}
|
|
84
157
|
|
|
85
|
-
const documentationRecords = getDocumentationRecords(
|
|
158
|
+
const documentationRecords = await getDocumentationRecords(
|
|
86
159
|
callExpression,
|
|
87
160
|
documentationAliases,
|
|
88
161
|
factory,
|
|
89
162
|
diagnostics,
|
|
90
163
|
true
|
|
91
164
|
)
|
|
92
|
-
const choiceRecords = getChoiceRecords(callExpression, choiceAliases, factory, diagnostics)
|
|
93
|
-
|
|
165
|
+
const choiceRecords = await getChoiceRecords(callExpression, choiceAliases, factory, diagnostics)
|
|
166
|
+
const choiceSetRecords: Record[] = []
|
|
167
|
+
if (choiceRecords.length > 0) {
|
|
168
|
+
choiceSetRecords.push(
|
|
169
|
+
await factory.createRecord({
|
|
170
|
+
source: callExpression,
|
|
171
|
+
table: 'sys_choice_set',
|
|
172
|
+
properties: {
|
|
173
|
+
name: column.get('table').asString().getValue(),
|
|
174
|
+
element: column.get('name').asString().getValue(),
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
)
|
|
178
|
+
}
|
|
94
179
|
const columnType = COLUMN_API_TO_TYPE[callee] ?? column.get('columnType').asString().getValue()
|
|
95
180
|
return {
|
|
96
181
|
success: true,
|
|
97
|
-
value:
|
|
98
|
-
.createRecord({
|
|
182
|
+
value: (
|
|
183
|
+
await factory.createRecord({
|
|
99
184
|
source: callExpression,
|
|
100
185
|
table: 'sys_dictionary',
|
|
101
186
|
properties: column.transform(({ $ }) => ({
|
|
@@ -241,7 +326,7 @@ export const ColumnPlugin = Plugin.create({
|
|
|
241
326
|
xml_view: $.from('xmlView').toBoolean().def(false),
|
|
242
327
|
})),
|
|
243
328
|
})
|
|
244
|
-
|
|
329
|
+
).with(...documentationRecords, ...choiceRecords, ...choiceSetRecords),
|
|
245
330
|
}
|
|
246
331
|
},
|
|
247
332
|
},
|
|
@@ -25,6 +25,12 @@ export const CrossScopePrivilegePlugin = Plugin.create({
|
|
|
25
25
|
name: 'CrossScopePrivilegePlugin',
|
|
26
26
|
records: {
|
|
27
27
|
sys_scope_privilege: {
|
|
28
|
+
relationships: {
|
|
29
|
+
sys_scope: {
|
|
30
|
+
via: 'target_scope',
|
|
31
|
+
inverse: true,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
28
34
|
toShape(record) {
|
|
29
35
|
return {
|
|
30
36
|
success: true,
|
|
@@ -52,7 +58,7 @@ export const CrossScopePrivilegePlugin = Plugin.create({
|
|
|
52
58
|
{
|
|
53
59
|
shape: CallExpressionShape,
|
|
54
60
|
fileTypes: ['fluent'],
|
|
55
|
-
toRecord(callExpression, { factory, config, diagnostics }) {
|
|
61
|
+
async toRecord(callExpression, { factory, config, diagnostics }) {
|
|
56
62
|
if (callExpression.getCallee() !== 'CrossScopePrivilege') {
|
|
57
63
|
return { success: false }
|
|
58
64
|
}
|
|
@@ -60,9 +66,18 @@ export const CrossScopePrivilegePlugin = Plugin.create({
|
|
|
60
66
|
const csp = callExpression.getArgument(0).asObject().withAliasedKeys(crossScopeAliases)
|
|
61
67
|
generateDeprecatedDiagnostics(csp, diagnostics)
|
|
62
68
|
|
|
69
|
+
const targetScope = csp.get('targetScope')
|
|
70
|
+
const targetScopeRef = targetScope.isString()
|
|
71
|
+
? await factory.createReference({
|
|
72
|
+
source: targetScope,
|
|
73
|
+
table: 'sys_scope',
|
|
74
|
+
guid: targetScope,
|
|
75
|
+
})
|
|
76
|
+
: undefined
|
|
77
|
+
|
|
63
78
|
return {
|
|
64
79
|
success: true,
|
|
65
|
-
value: factory.createRecord({
|
|
80
|
+
value: await factory.createRecord({
|
|
66
81
|
source: callExpression,
|
|
67
82
|
table: 'sys_scope_privilege',
|
|
68
83
|
explicitId: csp.get('$id'),
|
|
@@ -70,7 +85,7 @@ export const CrossScopePrivilegePlugin = Plugin.create({
|
|
|
70
85
|
operation: $,
|
|
71
86
|
status: $,
|
|
72
87
|
target_name: $.from('targetName'),
|
|
73
|
-
target_scope: $.
|
|
88
|
+
target_scope: $.val(targetScopeRef),
|
|
74
89
|
target_type: $.from('targetType'),
|
|
75
90
|
source_scope: $.val(config.scopeId),
|
|
76
91
|
})),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { path as pathModule, Plugin, Shape, StringShape, ts } from '@servicenow/sdk-build-core'
|
|
1
|
+
import { path as pathModule, Plugin, type ProjectFile, Shape, StringShape, ts } from '@servicenow/sdk-build-core'
|
|
2
2
|
import { applyPathMappings } from './utils'
|
|
3
3
|
|
|
4
4
|
const HTML_IMPORT_PREFIX = `<!-- @fluent-import-html`
|
|
@@ -66,7 +66,17 @@ export const HtmlImportPlugin = Plugin.create({
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
const mappedPath = applyPathMappings(projectRelativePath, config.staticContentPaths)
|
|
69
|
-
|
|
69
|
+
|
|
70
|
+
let htmlFile: ProjectFile
|
|
71
|
+
try {
|
|
72
|
+
htmlFile = project.addFile(mappedPath, { resolveDependencies: false, excludeFromCompiler: true })
|
|
73
|
+
} catch (e) {
|
|
74
|
+
diagnostics.error(
|
|
75
|
+
importDeclaration,
|
|
76
|
+
`failed to add HTML file: ${e instanceof Error ? e.message : String(e)}`
|
|
77
|
+
)
|
|
78
|
+
return { success: false }
|
|
79
|
+
}
|
|
70
80
|
|
|
71
81
|
return {
|
|
72
82
|
success: true,
|
package/src/index.ts
CHANGED
|
@@ -33,7 +33,8 @@ export * from './rest-api-plugin'
|
|
|
33
33
|
export * from './html-import-plugin'
|
|
34
34
|
export * from './static-content-plugin'
|
|
35
35
|
export * from './script-action-plugin'
|
|
36
|
+
export * from './claims-plugin'
|
|
36
37
|
|
|
37
38
|
// non-plugins
|
|
38
39
|
export * from './atf/step-configs'
|
|
39
|
-
export { REPACK_OUTPUT_DIR } from './repack'
|
|
40
|
+
export { REPACK_OUTPUT_DIR, checkModuleExists } from './repack'
|
package/src/json-plugin.ts
CHANGED
|
@@ -27,9 +27,14 @@ export class JsonStringifyShape extends CallExpressionShape {
|
|
|
27
27
|
export class JsonFileShape extends SourceFileShape {
|
|
28
28
|
private readonly json: ObjectShape
|
|
29
29
|
|
|
30
|
-
constructor(
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
constructor({
|
|
31
|
+
source,
|
|
32
|
+
json,
|
|
33
|
+
path,
|
|
34
|
+
content,
|
|
35
|
+
}: { source: Source; json: unknown; path: string | Shape; content: string | Shape }) {
|
|
36
|
+
super({ source, path, content })
|
|
37
|
+
this.json = Shape.from(source, json).asObject('Expected JSON file content to be a JSON object')
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
getJson(): ObjectShape {
|
|
@@ -43,23 +48,38 @@ export const JsonPlugin = Plugin.create({
|
|
|
43
48
|
{
|
|
44
49
|
shape: SourceFileShape,
|
|
45
50
|
fileTypes: ['json'],
|
|
46
|
-
toSubclass(file) {
|
|
47
|
-
const
|
|
48
|
-
|
|
51
|
+
async toSubclass(file, { compiler, transform }) {
|
|
52
|
+
const actualFile = compiler.getSourceFile(file.getPath())
|
|
53
|
+
if (!actualFile) {
|
|
54
|
+
return {
|
|
55
|
+
success: true,
|
|
56
|
+
value: new JsonFileShape({
|
|
57
|
+
source: file,
|
|
58
|
+
path: file.getPath(),
|
|
59
|
+
content: file.getContent(),
|
|
60
|
+
json: JSON5.parse(file.getContent()),
|
|
61
|
+
}),
|
|
62
|
+
}
|
|
63
|
+
}
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
const root = actualFile.getFirstDescendantByKind(ts.SyntaxKind.ObjectLiteralExpression)
|
|
66
|
+
if (!root) {
|
|
67
|
+
return { success: false }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const json = await transform.toShape(root)
|
|
71
|
+
if (!json.success) {
|
|
72
|
+
return { success: false }
|
|
58
73
|
}
|
|
59
74
|
|
|
60
75
|
return {
|
|
61
76
|
success: true,
|
|
62
|
-
value: new JsonFileShape(
|
|
77
|
+
value: new JsonFileShape({
|
|
78
|
+
source: file,
|
|
79
|
+
json: json.value,
|
|
80
|
+
path: file.getPath(),
|
|
81
|
+
content: file.getContent(),
|
|
82
|
+
}),
|
|
63
83
|
}
|
|
64
84
|
},
|
|
65
85
|
},
|