@servicenow/sdk-build-plugins 4.0.1 → 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
package/src/list-plugin.ts
CHANGED
|
@@ -37,6 +37,7 @@ export const ListPlugin = Plugin.create({
|
|
|
37
37
|
name: 'ListPlugin',
|
|
38
38
|
records: {
|
|
39
39
|
sys_ui_list: {
|
|
40
|
+
composite: true,
|
|
40
41
|
coalesce: ['name', 'view', 'sys_domain', 'element', 'relationship', 'parent'],
|
|
41
42
|
relationships: {
|
|
42
43
|
sys_ui_list_element: {
|
|
@@ -126,12 +127,17 @@ export const ListPlugin = Plugin.create({
|
|
|
126
127
|
}
|
|
127
128
|
})
|
|
128
129
|
|
|
129
|
-
const child = root.ele('sys_ui_list', { action:
|
|
130
|
+
const child = root.ele('sys_ui_list', { action: list.getAction() })
|
|
130
131
|
child.ele('sys_id').txt(list.getId().getValue())
|
|
131
132
|
child.ele('sys_scope', { display_value: config.scope }).txt(config.scopeId)
|
|
132
133
|
|
|
133
|
-
const view = list.get('view')
|
|
134
|
-
|
|
134
|
+
const view = list.get('view')
|
|
135
|
+
if (view.isRecordId() || view.isRecord()) {
|
|
136
|
+
const viewId = view.isRecordId() ? view : view.getId()
|
|
137
|
+
child.ele('view', viewId.resolveKeys()).txt(viewId.getValue())
|
|
138
|
+
} else {
|
|
139
|
+
child.ele('view').txt(view.asString().getValue())
|
|
140
|
+
}
|
|
135
141
|
|
|
136
142
|
const name = list.get('name')
|
|
137
143
|
if (name.isDefined()) {
|
|
@@ -153,6 +159,7 @@ export const ListPlugin = Plugin.create({
|
|
|
153
159
|
return {
|
|
154
160
|
success: true,
|
|
155
161
|
value: {
|
|
162
|
+
source: list,
|
|
156
163
|
name: `sys_ui_list_${list.getId().getValue()}.xml`,
|
|
157
164
|
category: list.getInstallCategory(),
|
|
158
165
|
content: xml.end({ prettyPrint: true }),
|
|
@@ -175,46 +182,48 @@ export const ListPlugin = Plugin.create({
|
|
|
175
182
|
|
|
176
183
|
const arg = callExpression.getArgument(0).asObject()
|
|
177
184
|
const columns = arg.get('columns').ifArray()?.getElements() ?? []
|
|
178
|
-
const
|
|
185
|
+
const view = arg.get('view')
|
|
186
|
+
const viewReference = view.isString()
|
|
187
|
+
? await factory.createReference({
|
|
188
|
+
source: view,
|
|
189
|
+
table: 'sys_ui_view',
|
|
190
|
+
keys: { name: view },
|
|
191
|
+
})
|
|
192
|
+
: view
|
|
193
|
+
|
|
194
|
+
const list = await factory.createRecord({
|
|
179
195
|
source: callExpression,
|
|
180
196
|
table: 'sys_ui_list',
|
|
181
197
|
explicitId: arg.get('$id'),
|
|
182
198
|
properties: arg.transform(({ $ }) => ({
|
|
183
199
|
name: $.from('table'),
|
|
184
|
-
view: $.
|
|
185
|
-
v.ifString()
|
|
186
|
-
? factory.createReference({
|
|
187
|
-
source: v,
|
|
188
|
-
table: 'sys_ui_view',
|
|
189
|
-
keys: {
|
|
190
|
-
name: v,
|
|
191
|
-
},
|
|
192
|
-
})
|
|
193
|
-
: v
|
|
194
|
-
),
|
|
200
|
+
view: $.val(viewReference),
|
|
195
201
|
parent: $,
|
|
196
202
|
relationship: $.map((v) => v.if([Record, StringShape])),
|
|
197
203
|
sys_domain: $.val('global'), // TODO: Domain support?
|
|
198
204
|
})),
|
|
199
205
|
})
|
|
200
206
|
|
|
207
|
+
const columnRecords: Record[] = []
|
|
208
|
+
for (const [index, column] of columns.entries()) {
|
|
209
|
+
columnRecords.push(
|
|
210
|
+
await factory.createRecord({
|
|
211
|
+
source: callExpression,
|
|
212
|
+
table: 'sys_ui_list_element',
|
|
213
|
+
properties: {
|
|
214
|
+
list_id: list,
|
|
215
|
+
position: index,
|
|
216
|
+
...(column.isString()
|
|
217
|
+
? { element: column }
|
|
218
|
+
: generateListColumnProps(column.asObject(), index, diagnostics)),
|
|
219
|
+
},
|
|
220
|
+
})
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
201
224
|
return {
|
|
202
225
|
success: true,
|
|
203
|
-
value: list.with(
|
|
204
|
-
...columns.map((column, index) =>
|
|
205
|
-
factory.createRecord({
|
|
206
|
-
source: callExpression,
|
|
207
|
-
table: 'sys_ui_list_element',
|
|
208
|
-
properties: {
|
|
209
|
-
list_id: list,
|
|
210
|
-
position: index,
|
|
211
|
-
...(column.isString()
|
|
212
|
-
? { element: column }
|
|
213
|
-
: generateListColumnProps(column.asObject(), index, diagnostics)),
|
|
214
|
-
},
|
|
215
|
-
})
|
|
216
|
-
)
|
|
217
|
-
),
|
|
226
|
+
value: list.with(...columnRecords),
|
|
218
227
|
}
|
|
219
228
|
},
|
|
220
229
|
},
|
package/src/now-config-plugin.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NowConfig, ObjectShape, Plugin, Shape } from '@servicenow/sdk-build-core'
|
|
1
|
+
import { NowConfig, ObjectShape, MODULE_RESOLUTION, Plugin, Shape } from '@servicenow/sdk-build-core'
|
|
2
2
|
|
|
3
3
|
import { JsonFileShape } from './json-plugin'
|
|
4
4
|
|
|
@@ -14,9 +14,8 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
14
14
|
],
|
|
15
15
|
records: {
|
|
16
16
|
sys_app: {
|
|
17
|
-
toShape(record, { packageJson }) {
|
|
17
|
+
toShape(record, { packageJson, config }) {
|
|
18
18
|
const { name: packageName } = packageJson
|
|
19
|
-
|
|
20
19
|
return {
|
|
21
20
|
success: true,
|
|
22
21
|
value: new NowConfigShape({
|
|
@@ -114,6 +113,9 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
114
113
|
logo: $.toString().def(''),
|
|
115
114
|
guidedSetupGuid: $.from('guided_setup_guid').toString().def(''),
|
|
116
115
|
installedAsDependency: $.from('installed_as_dependency').toBoolean().def(false),
|
|
116
|
+
packageResolverVersion: $.from('package_resolver_version').def(
|
|
117
|
+
config.scope === 'global' ? MODULE_RESOLUTION.V2 : MODULE_RESOLUTION.V1
|
|
118
|
+
),
|
|
117
119
|
})),
|
|
118
120
|
}),
|
|
119
121
|
}
|
|
@@ -123,7 +125,7 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
123
125
|
shapes: [
|
|
124
126
|
{
|
|
125
127
|
shape: JsonFileShape,
|
|
126
|
-
toRecord(file, { factory, config: rawConfig, packageJson }) {
|
|
128
|
+
async toRecord(file, { factory, config: rawConfig, packageJson, diagnostics }) {
|
|
127
129
|
if (file.getBaseName() !== NowConfig.FILE_NAME) {
|
|
128
130
|
return { success: false }
|
|
129
131
|
}
|
|
@@ -134,12 +136,19 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
134
136
|
const { name: packageName, version } = packageJson
|
|
135
137
|
const name = config.get('name').isDefined() ? config.get('name').asString().getValue() : packageName
|
|
136
138
|
|
|
139
|
+
let packageJsonPath: string
|
|
140
|
+
try {
|
|
141
|
+
packageJsonPath = NowConfig.moduleResolutionPath(rawConfig, packageJson, false, 'package.json')
|
|
142
|
+
} catch (e: any) {
|
|
143
|
+
diagnostics.error(file, e.message)
|
|
144
|
+
}
|
|
145
|
+
|
|
137
146
|
const accessControls = config.get('accessControls').ifDefined()?.asObject()
|
|
138
147
|
const licensing = config.get('licensing').ifDefined()?.asObject()
|
|
139
148
|
|
|
140
149
|
return {
|
|
141
150
|
success: true,
|
|
142
|
-
value: factory.createRecord({
|
|
151
|
+
value: await factory.createRecord({
|
|
143
152
|
source: config,
|
|
144
153
|
table: 'sys_app',
|
|
145
154
|
properties: config.transform(({ $ }) => ({
|
|
@@ -176,15 +185,17 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
176
185
|
trackable: $.val(accessControls?.get('trackable')).toBoolean().def(true),
|
|
177
186
|
uninstall_blocked: $.val(accessControls?.get('uninstallBlocked')).toBoolean().def(false),
|
|
178
187
|
hide_on_ui: $.val(accessControls?.get('hideOnUI')).toBoolean().def(false),
|
|
179
|
-
installed_as_dependency: $.toBoolean().def(false),
|
|
188
|
+
installed_as_dependency: $.from('installedAsDependency').toBoolean().def(false),
|
|
180
189
|
license_category: $.val(licensing?.get('licenseCategory')).toString().def('none'),
|
|
181
|
-
|
|
182
190
|
scope: $.val(scope),
|
|
183
|
-
package_json: $.val(
|
|
191
|
+
package_json: $.val(packageJsonPath),
|
|
184
192
|
name: $.val(name),
|
|
185
193
|
source: $.val(scope),
|
|
186
194
|
sys_id: $.from('scopeId'),
|
|
187
195
|
version: $.val(version),
|
|
196
|
+
package_resolver_version: $.from('packageResolverVersion').def(
|
|
197
|
+
scope === 'global' ? MODULE_RESOLUTION.V2 : MODULE_RESOLUTION.V1
|
|
198
|
+
),
|
|
188
199
|
})),
|
|
189
200
|
}),
|
|
190
201
|
}
|
|
@@ -1,45 +1,53 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type ts,
|
|
3
2
|
path as pathModule,
|
|
4
3
|
CallExpressionShape,
|
|
5
4
|
Plugin,
|
|
6
5
|
type ProjectFile,
|
|
6
|
+
type Record,
|
|
7
7
|
type Source,
|
|
8
8
|
StringShape,
|
|
9
9
|
Shape,
|
|
10
|
+
FileSystem,
|
|
11
|
+
type Transform,
|
|
10
12
|
} from '@servicenow/sdk-build-core'
|
|
11
13
|
import { CallExpressionPlugin } from './call-expression-plugin'
|
|
12
14
|
|
|
13
15
|
export class NowIncludeShape extends CallExpressionShape {
|
|
14
|
-
private readonly
|
|
16
|
+
private readonly includedText: string
|
|
15
17
|
|
|
16
|
-
constructor({ source, path,
|
|
18
|
+
constructor({ source, path, includedText }: { source: Source; path: string; includedText: string }) {
|
|
17
19
|
super({ source, callee: 'Now.include', args: [path] })
|
|
18
|
-
this.
|
|
20
|
+
this.includedText = includedText
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
getPath(): string {
|
|
22
24
|
return this.getArgument(0).asString().getValue()
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
return this.
|
|
27
|
+
override getValue(): string {
|
|
28
|
+
return this.includedText
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
return
|
|
31
|
+
override toString(): StringShape {
|
|
32
|
+
return Shape.from(this, this.getValue()).asString().withContentType('cdata')
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
override equals(other: unknown): boolean {
|
|
36
|
+
if (typeof other === 'string') {
|
|
37
|
+
return this.includedText === other
|
|
38
|
+
} else if (other instanceof Shape) {
|
|
39
|
+
return other.equals(this.includedText)
|
|
40
|
+
} else {
|
|
41
|
+
return super.equals(other)
|
|
42
|
+
}
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
static async fromRecord(record: Record, text: string | Shape, transform: Transform): Promise<NowIncludeShape> {
|
|
46
|
+
return new NowIncludeShape({
|
|
47
|
+
source: record,
|
|
48
|
+
path: `./${await transform.getUpdateName(record)}.js`,
|
|
49
|
+
includedText: text instanceof Shape ? text.toString().getValue() : text,
|
|
50
|
+
})
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
|
|
@@ -61,7 +69,6 @@ export const NowIncludePlugin = Plugin.create({
|
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
const path = arg.getValue()
|
|
64
|
-
|
|
65
72
|
if (!/^\.\.?\/.*$/.test(path.trim()) && path.includes('/')) {
|
|
66
73
|
diagnostics.error(arg, 'Now.include() argument must be a relative path')
|
|
67
74
|
return { success: false }
|
|
@@ -86,38 +93,64 @@ export const NowIncludePlugin = Plugin.create({
|
|
|
86
93
|
|
|
87
94
|
return {
|
|
88
95
|
success: true,
|
|
89
|
-
value: new NowIncludeShape({
|
|
96
|
+
value: new NowIncludeShape({
|
|
97
|
+
source: callExpression,
|
|
98
|
+
path,
|
|
99
|
+
includedText: includedFile.getContent(),
|
|
100
|
+
}),
|
|
90
101
|
}
|
|
91
102
|
},
|
|
92
103
|
},
|
|
93
104
|
{
|
|
94
105
|
shape: NowIncludeShape,
|
|
95
|
-
async commit(shape, target, { transform, commit }) {
|
|
106
|
+
async commit(shape, target, { transform, commit, project, fs }) {
|
|
96
107
|
const targetResult = await transform.toShape(target)
|
|
97
108
|
if (!targetResult.success) {
|
|
98
109
|
return { success: false }
|
|
99
110
|
}
|
|
100
111
|
|
|
112
|
+
const targetDirPath = target.getSourceFile().getDirectoryPath()
|
|
113
|
+
const targetPath = project.resolvePath(targetDirPath, shape.getPath())
|
|
114
|
+
|
|
101
115
|
const { value: targetShape } = targetResult
|
|
116
|
+
if (targetShape.equals(shape.getValue())) {
|
|
117
|
+
return { success: true }
|
|
118
|
+
}
|
|
119
|
+
|
|
102
120
|
if (targetShape.is(NowIncludeShape)) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
121
|
+
// Never update the path of an existing Now.include() - just update the file content
|
|
122
|
+
project
|
|
123
|
+
.getFile(project.resolvePath(targetDirPath, targetShape.getPath()))
|
|
124
|
+
.setContent(shape.getValue())
|
|
125
|
+
} else if (targetShape.is(CallExpressionShape) && targetShape.getCallee() === 'Now.include') {
|
|
126
|
+
// TODO: This is hacky AF. When Now.include() is generated for the first time, it's
|
|
127
|
+
// just written to the file using getCode() which doesn't generate any file at the
|
|
128
|
+
// included path. Therefore, the shape is not parsed into a NowIncludeShape because
|
|
129
|
+
// we check if the file exists and return success: false if it doesn't. So it just
|
|
130
|
+
// comes back as a generic CallExpressionShape.
|
|
131
|
+
await commit(shape, target, CallExpressionPlugin)
|
|
132
|
+
if (FileSystem.existsSync(fs, targetPath)) {
|
|
133
|
+
project
|
|
134
|
+
.addFile(targetPath, { resolveDependencies: false, excludeFromCompiler: true })
|
|
135
|
+
.setContent(shape.getValue())
|
|
136
|
+
} else {
|
|
137
|
+
project.addFile(
|
|
138
|
+
{ path: targetPath, content: shape.getValue() },
|
|
139
|
+
{ resolveDependencies: false, excludeFromCompiler: true }
|
|
140
|
+
)
|
|
106
141
|
}
|
|
107
142
|
} else {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
143
|
+
// If we reach this point it's likely an inline string literal or some other value that
|
|
144
|
+
// just needs to be replaced.
|
|
145
|
+
target.replaceWithText(shape.toString().getCode())
|
|
112
146
|
}
|
|
113
147
|
|
|
114
|
-
await commit(shape, target, CallExpressionPlugin)
|
|
115
148
|
return { success: true }
|
|
116
149
|
},
|
|
117
150
|
},
|
|
118
151
|
{
|
|
119
152
|
shape: StringShape,
|
|
120
|
-
async commit(shape, target, { transform }) {
|
|
153
|
+
async commit(shape, target, { transform, project }) {
|
|
121
154
|
const targetResult = await transform.toShape(target)
|
|
122
155
|
if (!targetResult.success) {
|
|
123
156
|
return { success: false }
|
|
@@ -128,8 +161,9 @@ export const NowIncludePlugin = Plugin.create({
|
|
|
128
161
|
return { success: false }
|
|
129
162
|
}
|
|
130
163
|
|
|
131
|
-
|
|
132
|
-
|
|
164
|
+
if (!shape.equals(targetShape.getValue())) {
|
|
165
|
+
const targetDirPath = target.getSourceFile().getDirectoryPath()
|
|
166
|
+
const file = project.getFile(project.resolvePath(targetDirPath, targetShape.getPath()))
|
|
133
167
|
file.setContent(shape.getValue())
|
|
134
168
|
}
|
|
135
169
|
|
package/src/now-ref-plugin.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Plugin,
|
|
6
6
|
type ObjectShape,
|
|
7
7
|
Shape,
|
|
8
|
+
NowConfig,
|
|
8
9
|
} from '@servicenow/sdk-build-core'
|
|
9
10
|
import { RepackService } from './repack'
|
|
10
11
|
import { JsonFileShape } from './json-plugin'
|
|
@@ -20,22 +21,22 @@ export const PackageJsonPlugin = Plugin.create({
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
const relativePath = pathModule.relative(project.getRootDir(), file.getPath())
|
|
23
|
-
const sysModulePath =
|
|
24
|
+
const sysModulePath = NowConfig.moduleResolutionPath(config, packageJson, false, relativePath)
|
|
24
25
|
|
|
25
|
-
const sbomRecord = factory.createRecord({
|
|
26
|
+
const sbomRecord = await factory.createRecord({
|
|
26
27
|
source: file,
|
|
27
28
|
table: 'sys_module',
|
|
28
29
|
explicitId: 'bom_json',
|
|
29
30
|
properties: {
|
|
30
|
-
path:
|
|
31
|
+
path: NowConfig.moduleResolutionPath(config, packageJson, false, 'bom.json'),
|
|
31
32
|
external_source: false,
|
|
32
33
|
},
|
|
33
34
|
})
|
|
34
35
|
|
|
35
36
|
return {
|
|
36
37
|
success: true,
|
|
37
|
-
value:
|
|
38
|
-
.createRecord({
|
|
38
|
+
value: (
|
|
39
|
+
await factory.createRecord({
|
|
39
40
|
source: file,
|
|
40
41
|
table: 'sys_module',
|
|
41
42
|
explicitId: relativePath.replaceAll(/[./\\]/g, '_'),
|
|
@@ -56,7 +57,7 @@ export const PackageJsonPlugin = Plugin.create({
|
|
|
56
57
|
sys_name: sysModulePath,
|
|
57
58
|
},
|
|
58
59
|
})
|
|
59
|
-
|
|
60
|
+
).with(sbomRecord),
|
|
60
61
|
}
|
|
61
62
|
},
|
|
62
63
|
},
|
package/src/property-plugin.ts
CHANGED
package/src/record-plugin.ts
CHANGED
|
@@ -29,6 +29,9 @@ export const RecordPlugin = Plugin.create({
|
|
|
29
29
|
name: 'RecordPlugin',
|
|
30
30
|
records: {
|
|
31
31
|
'*': {
|
|
32
|
+
getUpdateName(record) {
|
|
33
|
+
return { success: true, value: `${record.getTable()}_${record.getId().getValue()}` }
|
|
34
|
+
},
|
|
32
35
|
toShape(record) {
|
|
33
36
|
return {
|
|
34
37
|
success: true,
|
|
@@ -52,21 +55,34 @@ export const RecordPlugin = Plugin.create({
|
|
|
52
55
|
}),
|
|
53
56
|
}
|
|
54
57
|
},
|
|
55
|
-
toFile(record, { config }) {
|
|
58
|
+
async toFile(record, { config, database, transform }) {
|
|
56
59
|
const recordBuilder = unloadBuilder(config)
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
const builder = recordBuilder.record(record)
|
|
60
|
+
const updateName = await transform.getUpdateName(record)
|
|
61
|
+
const builder = recordBuilder.record(record, updateName)
|
|
60
62
|
|
|
61
63
|
record
|
|
62
64
|
.entries()
|
|
63
65
|
.sort(([a], [b]) => a.localeCompare(b)) // Sort keys to make outputs more deterministic
|
|
64
66
|
.forEach(([prop, shape]) => builder.field(prop, shape))
|
|
65
67
|
|
|
68
|
+
const claims = database
|
|
69
|
+
.query('sys_claim')
|
|
70
|
+
.filter((claim) => claim.get('metadata_update_name').equals(updateName))
|
|
71
|
+
|
|
72
|
+
for (const claim of claims) {
|
|
73
|
+
const claimUpdateName = await transform.getUpdateName(claim)
|
|
74
|
+
const claimBuilder = recordBuilder.record(claim, claimUpdateName)
|
|
75
|
+
claim
|
|
76
|
+
.entries()
|
|
77
|
+
.sort(([a], [b]) => a.localeCompare(b)) // Sort keys to make outputs more deterministic
|
|
78
|
+
.forEach(([prop, shape]) => claimBuilder.field(prop, shape))
|
|
79
|
+
}
|
|
80
|
+
|
|
66
81
|
return {
|
|
67
82
|
success: true,
|
|
68
83
|
value: {
|
|
69
|
-
|
|
84
|
+
source: record,
|
|
85
|
+
name: `${updateName}.xml`,
|
|
70
86
|
category: record.getInstallCategory(),
|
|
71
87
|
content: recordBuilder.end(),
|
|
72
88
|
},
|
|
@@ -78,7 +94,7 @@ export const RecordPlugin = Plugin.create({
|
|
|
78
94
|
{
|
|
79
95
|
shape: CallExpressionShape,
|
|
80
96
|
fileTypes: ['fluent'],
|
|
81
|
-
toRecord(callExpression, { factory, diagnostics }) {
|
|
97
|
+
async toRecord(callExpression, { factory, diagnostics }) {
|
|
82
98
|
if (callExpression.getCallee() !== 'Record') {
|
|
83
99
|
return { success: false }
|
|
84
100
|
}
|
|
@@ -94,7 +110,7 @@ export const RecordPlugin = Plugin.create({
|
|
|
94
110
|
}
|
|
95
111
|
return {
|
|
96
112
|
success: true,
|
|
97
|
-
value: factory.createRecord({
|
|
113
|
+
value: await factory.createRecord({
|
|
98
114
|
source: callExpression,
|
|
99
115
|
table,
|
|
100
116
|
explicitId: record.get('$id'),
|
|
@@ -107,9 +123,9 @@ export const RecordPlugin = Plugin.create({
|
|
|
107
123
|
files: [
|
|
108
124
|
{
|
|
109
125
|
matcher: /\.xml$/,
|
|
110
|
-
toRecord(file, { parser, logger }) {
|
|
126
|
+
async toRecord(file, { parser, logger }) {
|
|
111
127
|
try {
|
|
112
|
-
const [first, ...rest] = parser.parsePayload(file)
|
|
128
|
+
const [first, ...rest] = await parser.parsePayload(file)
|
|
113
129
|
|
|
114
130
|
if (!first) {
|
|
115
131
|
return { success: false }
|
package/src/repack/index.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { path } from '@servicenow/sdk-build-core'
|
|
2
2
|
import type { DependencyNode, RepackOptions } from '@servicenow/sdk-repack'
|
|
3
3
|
|
|
4
|
+
export async function checkModuleExists(
|
|
5
|
+
module: string,
|
|
6
|
+
logger: RepackOptions['logger'],
|
|
7
|
+
fs: RepackOptions['fs'],
|
|
8
|
+
workingDir: RepackOptions['workingDir']
|
|
9
|
+
) {
|
|
10
|
+
const repackService = await RepackService.create(logger, fs, workingDir)
|
|
11
|
+
return repackService.checkModuleExists(module)
|
|
12
|
+
}
|
|
13
|
+
|
|
4
14
|
export const REPACK_OUTPUT_DIR = path.join('.now', '.output')
|
|
5
15
|
|
|
6
16
|
export class RepackService {
|
|
@@ -38,4 +48,8 @@ export class RepackService {
|
|
|
38
48
|
logger: this.logger!,
|
|
39
49
|
})
|
|
40
50
|
}
|
|
51
|
+
|
|
52
|
+
async checkModuleExists(module: string) {
|
|
53
|
+
return this.repack.checkModuleExists(module, this.fs, this.workingDir, this.logger!)
|
|
54
|
+
}
|
|
41
55
|
}
|
package/src/rest-api-plugin.ts
CHANGED
|
@@ -94,7 +94,7 @@ function getVersionId(
|
|
|
94
94
|
return versionToVersionRecordMap.get(`v${version}`)!.getId()
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
function generateVersionRecords(
|
|
97
|
+
async function generateVersionRecords(
|
|
98
98
|
versions: Shape[],
|
|
99
99
|
restApi: ObjectShape,
|
|
100
100
|
restRecord: Record,
|
|
@@ -102,12 +102,12 @@ function generateVersionRecords(
|
|
|
102
102
|
factory: Factory,
|
|
103
103
|
diagnostics: Diagnostics,
|
|
104
104
|
callExpression: CallExpressionShape
|
|
105
|
-
): Map<string, Record
|
|
105
|
+
): Promise<Map<string, Record>> {
|
|
106
106
|
const versionMap = new Map<string, Record>()
|
|
107
107
|
for (const v of versions) {
|
|
108
108
|
const version = v.asObject().get('version').getValue()
|
|
109
109
|
const versionId = `v${version}`
|
|
110
|
-
const versionRecord = factory.createRecord({
|
|
110
|
+
const versionRecord = await factory.createRecord({
|
|
111
111
|
source: callExpression,
|
|
112
112
|
table: 'sys_ws_version',
|
|
113
113
|
explicitId: v.asObject().get('$id'),
|
|
@@ -155,7 +155,7 @@ function checkForDuplicateRecords(
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
function generateRouteAttributeRecords(
|
|
158
|
+
async function generateRouteAttributeRecords(
|
|
159
159
|
attributes: Shape[],
|
|
160
160
|
restDef: Record,
|
|
161
161
|
routeDef: Record,
|
|
@@ -164,10 +164,10 @@ function generateRouteAttributeRecords(
|
|
|
164
164
|
factory: Factory,
|
|
165
165
|
diagnostics: Diagnostics,
|
|
166
166
|
callExpression: CallExpressionShape
|
|
167
|
-
): Record[] {
|
|
167
|
+
): Promise<Record[]> {
|
|
168
168
|
const records: Record[] = []
|
|
169
169
|
for (const attr of attributes) {
|
|
170
|
-
const attrRecord = factory.createRecord({
|
|
170
|
+
const attrRecord = await factory.createRecord({
|
|
171
171
|
source: callExpression,
|
|
172
172
|
table: `sys_ws_${attrType}`,
|
|
173
173
|
explicitId: attr.asObject().get('$id'),
|
|
@@ -182,7 +182,7 @@ function generateRouteAttributeRecords(
|
|
|
182
182
|
|
|
183
183
|
checkForDuplicateRecords(attrMap, attrRecord, attr.asObject(), diagnostics)
|
|
184
184
|
|
|
185
|
-
const attributeMappingRecord = factory.createRecord({
|
|
185
|
+
const attributeMappingRecord = await factory.createRecord({
|
|
186
186
|
source: callExpression,
|
|
187
187
|
table: `sys_ws_${attrType}_map`,
|
|
188
188
|
properties: attr.asObject().transform(({ $ }) => ({
|
|
@@ -197,7 +197,7 @@ function generateRouteAttributeRecords(
|
|
|
197
197
|
return records
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
function generateRouteAndRouteAttrRecords(
|
|
200
|
+
async function generateRouteAndRouteAttrRecords(
|
|
201
201
|
routes: Shape[],
|
|
202
202
|
restDef: Record,
|
|
203
203
|
factory: Factory,
|
|
@@ -205,7 +205,7 @@ function generateRouteAndRouteAttrRecords(
|
|
|
205
205
|
diagnostics: Diagnostics,
|
|
206
206
|
versionToVersionRecordMap: Map<string, Record>,
|
|
207
207
|
callExpression: CallExpressionShape
|
|
208
|
-
): Record[] {
|
|
208
|
+
): Promise<Record[]> {
|
|
209
209
|
const routeRecords: Record[] = []
|
|
210
210
|
const headersMap = new Map<string, Record>()
|
|
211
211
|
const parametersMap = new Map<string, Record>()
|
|
@@ -246,7 +246,7 @@ function generateRouteAndRouteAttrRecords(
|
|
|
246
246
|
)
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
const routeRecord = factory.createRecord({
|
|
249
|
+
const routeRecord = await factory.createRecord({
|
|
250
250
|
source: callExpression,
|
|
251
251
|
table: 'sys_ws_operation',
|
|
252
252
|
explicitId: route.get('$id'),
|
|
@@ -285,7 +285,7 @@ function generateRouteAndRouteAttrRecords(
|
|
|
285
285
|
h.asObject().withAliasedKeys(attributeAliases)
|
|
286
286
|
generateDeprecatedDiagnostics(h.asObject(), diagnostics)
|
|
287
287
|
})
|
|
288
|
-
const headerRecords = generateRouteAttributeRecords(
|
|
288
|
+
const headerRecords = await generateRouteAttributeRecords(
|
|
289
289
|
routeHeaders,
|
|
290
290
|
restDef,
|
|
291
291
|
routeRecord,
|
|
@@ -301,7 +301,7 @@ function generateRouteAndRouteAttrRecords(
|
|
|
301
301
|
p.asObject().withAliasedKeys(attributeAliases)
|
|
302
302
|
generateDeprecatedDiagnostics(p.asObject(), diagnostics)
|
|
303
303
|
})
|
|
304
|
-
const parameterRecords = generateRouteAttributeRecords(
|
|
304
|
+
const parameterRecords = await generateRouteAttributeRecords(
|
|
305
305
|
routeParameters,
|
|
306
306
|
restDef,
|
|
307
307
|
routeRecord,
|
|
@@ -594,7 +594,7 @@ export const RestApiPlugin = Plugin.create({
|
|
|
594
594
|
}
|
|
595
595
|
|
|
596
596
|
const enforceAcls = restApi.get('enforceAcl')
|
|
597
|
-
const restRecord = factory.createRecord({
|
|
597
|
+
const restRecord = await factory.createRecord({
|
|
598
598
|
source: callExpression,
|
|
599
599
|
table: 'sys_ws_definition',
|
|
600
600
|
explicitId: restApi.get('$id'),
|
|
@@ -622,7 +622,7 @@ export const RestApiPlugin = Plugin.create({
|
|
|
622
622
|
enforce_acl: $.val(mergeAcls(enforceAcls)),
|
|
623
623
|
})),
|
|
624
624
|
})
|
|
625
|
-
const versionToVersionRecordMap = generateVersionRecords(
|
|
625
|
+
const versionToVersionRecordMap = await generateVersionRecords(
|
|
626
626
|
versions,
|
|
627
627
|
restApi,
|
|
628
628
|
restRecord,
|
|
@@ -638,7 +638,7 @@ export const RestApiPlugin = Plugin.create({
|
|
|
638
638
|
generateDeprecatedDiagnostics(r.asObject(), diagnostics)
|
|
639
639
|
})
|
|
640
640
|
|
|
641
|
-
const routeAndRouteAttrRecords = generateRouteAndRouteAttrRecords(
|
|
641
|
+
const routeAndRouteAttrRecords = await generateRouteAndRouteAttrRecords(
|
|
642
642
|
routes,
|
|
643
643
|
restRecord,
|
|
644
644
|
factory,
|