@servicenow/sdk-build-plugins 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AttachmentPlugin.d.ts +253 -0
- package/dist/AttachmentPlugin.js +216 -0
- package/dist/AttachmentPlugin.js.map +1 -0
- package/dist/BusinessRulePlugin.d.ts +56 -0
- package/dist/BusinessRulePlugin.js +171 -0
- package/dist/BusinessRulePlugin.js.map +1 -0
- package/dist/CrossScopePrivilegePlugin.d.ts +22 -0
- package/dist/CrossScopePrivilegePlugin.js +42 -0
- package/dist/CrossScopePrivilegePlugin.js.map +1 -0
- package/dist/DefaultPlugin.d.ts +71 -0
- package/dist/DefaultPlugin.js +238 -0
- package/dist/DefaultPlugin.js.map +1 -0
- package/dist/IdPlugin.d.ts +17 -0
- package/dist/IdPlugin.js +45 -0
- package/dist/IdPlugin.js.map +1 -0
- package/dist/ListPlugin.d.ts +91 -0
- package/dist/ListPlugin.js +398 -0
- package/dist/ListPlugin.js.map +1 -0
- package/dist/PropertyPlugin.d.ts +122 -0
- package/dist/PropertyPlugin.js +165 -0
- package/dist/PropertyPlugin.js.map +1 -0
- package/dist/ScriptTemplatePlugin.d.ts +31 -0
- package/dist/ScriptTemplatePlugin.js +208 -0
- package/dist/ScriptTemplatePlugin.js.map +1 -0
- package/dist/UserPreferencePlugin.d.ts +16 -0
- package/dist/UserPreferencePlugin.js +30 -0
- package/dist/UserPreferencePlugin.js.map +1 -0
- package/dist/aclAndRole/AclPlugin.d.ts +117 -0
- package/dist/aclAndRole/AclPlugin.js +285 -0
- package/dist/aclAndRole/AclPlugin.js.map +1 -0
- package/dist/aclAndRole/RolePlugin.d.ts +58 -0
- package/dist/aclAndRole/RolePlugin.js +152 -0
- package/dist/aclAndRole/RolePlugin.js.map +1 -0
- package/dist/aclAndRole/Util.d.ts +3 -0
- package/dist/aclAndRole/Util.js +106 -0
- package/dist/aclAndRole/Util.js.map +1 -0
- package/dist/app/ApplicationMenuPlugin.d.ts +32 -0
- package/dist/app/ApplicationMenuPlugin.js +106 -0
- package/dist/app/ApplicationMenuPlugin.js.map +1 -0
- package/dist/atf/ATFComposer.d.ts +492 -0
- package/dist/atf/ATFComposer.js +2717 -0
- package/dist/atf/ATFComposer.js.map +1 -0
- package/dist/atf/TestPlugin.d.ts +31 -0
- package/dist/atf/TestPlugin.js +95 -0
- package/dist/atf/TestPlugin.js.map +1 -0
- package/dist/atf/index.d.ts +1 -0
- package/dist/atf/index.js +9 -0
- package/dist/atf/index.js.map +1 -0
- package/dist/db/ColumnPlugins.d.ts +278 -0
- package/dist/db/ColumnPlugins.js +112 -0
- package/dist/db/ColumnPlugins.js.map +1 -0
- package/dist/db/RecordPlugin.d.ts +208 -0
- package/dist/db/RecordPlugin.js +287 -0
- package/dist/db/RecordPlugin.js.map +1 -0
- package/dist/db/TablePlugin.d.ts +742 -0
- package/dist/db/TablePlugin.js +1249 -0
- package/dist/db/TablePlugin.js.map +1 -0
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.js +27 -0
- package/dist/db/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/scriptedRESTAPI/RESTDeserializationUtils.d.ts +12 -0
- package/dist/scriptedRESTAPI/RESTDeserializationUtils.js +371 -0
- package/dist/scriptedRESTAPI/RESTDeserializationUtils.js.map +1 -0
- package/dist/scriptedRESTAPI/RESTSerializationUtils.d.ts +15 -0
- package/dist/scriptedRESTAPI/RESTSerializationUtils.js +177 -0
- package/dist/scriptedRESTAPI/RESTSerializationUtils.js.map +1 -0
- package/dist/scriptedRESTAPI/RestApiPlugin.d.ts +144 -0
- package/dist/scriptedRESTAPI/RestApiPlugin.js +318 -0
- package/dist/scriptedRESTAPI/RestApiPlugin.js.map +1 -0
- package/dist/scriptedRESTAPI/RestSchemaUtils.d.ts +190 -0
- package/dist/scriptedRESTAPI/RestSchemaUtils.js +53 -0
- package/dist/scriptedRESTAPI/RestSchemaUtils.js.map +1 -0
- package/dist/scriptedRESTAPI/RestUtils.d.ts +75 -0
- package/dist/scriptedRESTAPI/RestUtils.js +469 -0
- package/dist/scriptedRESTAPI/RestUtils.js.map +1 -0
- package/dist/scripts/ClientScriptPlugin.d.ts +43 -0
- package/dist/scripts/ClientScriptPlugin.js +190 -0
- package/dist/scripts/ClientScriptPlugin.js.map +1 -0
- package/dist/scripts/scriptUtils.d.ts +15 -0
- package/dist/scripts/scriptUtils.js +83 -0
- package/dist/scripts/scriptUtils.js.map +1 -0
- package/dist/uxf/ExperiencePlugin.d.ts +22 -0
- package/dist/uxf/ExperiencePlugin.js +55 -0
- package/dist/uxf/ExperiencePlugin.js.map +1 -0
- package/dist/uxf/RoutesPlugin.d.ts +22 -0
- package/dist/uxf/RoutesPlugin.js +176 -0
- package/dist/uxf/RoutesPlugin.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/cleanUxValue.d.ts +4 -0
- package/dist/uxf/UxfFormulaParser/cleanUxValue.js +65 -0
- package/dist/uxf/UxfFormulaParser/cleanUxValue.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/api.d.ts +189 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/api.js +158 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/api.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/clientTransformMap.d.ts +13 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/clientTransformMap.js +604 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/clientTransformMap.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/grammarParser.d.ts +12 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/grammarParser.js +551 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/grammarParser.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/spanHelpers.d.ts +31 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/spanHelpers.js +64 -0
- package/dist/uxf/UxfFormulaParser/grammerParser/spanHelpers.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/index.d.ts +3 -0
- package/dist/uxf/UxfFormulaParser/index.js +11 -0
- package/dist/uxf/UxfFormulaParser/index.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/parser.d.ts +8 -0
- package/dist/uxf/UxfFormulaParser/parser.js +87 -0
- package/dist/uxf/UxfFormulaParser/parser.js.map +1 -0
- package/dist/uxf/UxfFormulaParser/utils/getErrorMsg.d.ts +8 -0
- package/dist/uxf/UxfFormulaParser/utils/getErrorMsg.js +17 -0
- package/dist/uxf/UxfFormulaParser/utils/getErrorMsg.js.map +1 -0
- package/dist/uxf/constants.d.ts +2 -0
- package/dist/uxf/constants.js +8 -0
- package/dist/uxf/constants.js.map +1 -0
- package/dist/uxf/index.d.ts +2 -0
- package/dist/uxf/index.js +11 -0
- package/dist/uxf/index.js.map +1 -0
- package/dist/uxf/tectonicIdGenerator.d.ts +12 -0
- package/dist/uxf/tectonicIdGenerator.js +102 -0
- package/dist/uxf/tectonicIdGenerator.js.map +1 -0
- package/license +9 -0
- package/package.json +42 -0
- package/src/AttachmentPlugin.ts +262 -0
- package/src/BusinessRulePlugin.ts +251 -0
- package/src/CrossScopePrivilegePlugin.ts +54 -0
- package/src/DefaultPlugin.ts +272 -0
- package/src/IdPlugin.ts +47 -0
- package/src/ListPlugin.ts +497 -0
- package/src/PropertyPlugin.ts +218 -0
- package/src/ScriptTemplatePlugin.ts +223 -0
- package/src/UserPreferencePlugin.ts +36 -0
- package/src/aclAndRole/AclPlugin.ts +410 -0
- package/src/aclAndRole/RolePlugin.ts +225 -0
- package/src/aclAndRole/Util.ts +104 -0
- package/src/app/ApplicationMenuPlugin.ts +158 -0
- package/src/atf/ATFComposer.ts +3356 -0
- package/src/atf/TestPlugin.ts +119 -0
- package/src/atf/index.ts +1 -0
- package/src/db/ColumnPlugins.ts +117 -0
- package/src/db/RecordPlugin.ts +391 -0
- package/src/db/TablePlugin.ts +1581 -0
- package/src/db/index.ts +3 -0
- package/src/index.ts +16 -0
- package/src/scriptedRESTAPI/RESTDeserializationUtils.ts +410 -0
- package/src/scriptedRESTAPI/RESTSerializationUtils.ts +227 -0
- package/src/scriptedRESTAPI/RestApiPlugin.ts +438 -0
- package/src/scriptedRESTAPI/RestSchemaUtils.ts +72 -0
- package/src/scriptedRESTAPI/RestUtils.ts +507 -0
- package/src/scripts/ClientScriptPlugin.ts +251 -0
- package/src/scripts/scriptUtils.ts +81 -0
- package/src/uxf/ExperiencePlugin.ts +64 -0
- package/src/uxf/RoutesPlugin.ts +215 -0
- package/src/uxf/UxfFormulaParser/cleanUxValue.ts +73 -0
- package/src/uxf/UxfFormulaParser/grammerParser/api.js +166 -0
- package/src/uxf/UxfFormulaParser/grammerParser/clientTransformMap.js +606 -0
- package/src/uxf/UxfFormulaParser/grammerParser/grammarParser.js +551 -0
- package/src/uxf/UxfFormulaParser/grammerParser/spanHelpers.js +65 -0
- package/src/uxf/UxfFormulaParser/index.ts +4 -0
- package/src/uxf/UxfFormulaParser/parser.ts +64 -0
- package/src/uxf/UxfFormulaParser/utils/getErrorMsg.ts +13 -0
- package/src/uxf/constants.ts +4 -0
- package/src/uxf/index.ts +2 -0
- package/src/uxf/tectonicIdGenerator.ts +81 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import { RestApi, RestApiConfig, RestApiSchema, Version } from '@servicenow/sdk-core/runtime/rest'
|
|
2
|
+
import { Record, RecordWithLegacyId } from '@servicenow/sdk-core/runtime/db'
|
|
3
|
+
import {
|
|
4
|
+
linkDocument,
|
|
5
|
+
Context,
|
|
6
|
+
Plugin,
|
|
7
|
+
Document,
|
|
8
|
+
extractCallExpression,
|
|
9
|
+
getCallExpressionName,
|
|
10
|
+
generateCallExpressionExportForDocument,
|
|
11
|
+
getOrCreateEntitySourceFile,
|
|
12
|
+
getSysUpdateName,
|
|
13
|
+
EntityData,
|
|
14
|
+
ObjectData,
|
|
15
|
+
} from '@servicenow/sdk-build-core'
|
|
16
|
+
import { RecordPlugin } from '../db/RecordPlugin'
|
|
17
|
+
import { buildScriptImport, scriptInfo, type ScriptInfo } from '../scripts/scriptUtils'
|
|
18
|
+
import {
|
|
19
|
+
EnforceAcl,
|
|
20
|
+
mergeACLIds,
|
|
21
|
+
generateVersionRecords,
|
|
22
|
+
generateRoutesAndRouteAttrRecords,
|
|
23
|
+
} from './RESTSerializationUtils'
|
|
24
|
+
import * as ts from 'ts-morph'
|
|
25
|
+
import {
|
|
26
|
+
transformDefinition,
|
|
27
|
+
transformRestAttrs,
|
|
28
|
+
transformRouteAttrs,
|
|
29
|
+
transformRouteAttrsMap,
|
|
30
|
+
transformRoutes,
|
|
31
|
+
} from './RESTDeserializationUtils'
|
|
32
|
+
import { RestRouteHeaderMap, RestRouteQueryMap } from './RestSchemaUtils'
|
|
33
|
+
import {
|
|
34
|
+
getRestDocumentMap,
|
|
35
|
+
getRouteAttrResult,
|
|
36
|
+
getRouteAttrMapResult,
|
|
37
|
+
getRouteAttrWithRecordNodeResult,
|
|
38
|
+
getRouteAttrWithRestNodeResult,
|
|
39
|
+
getRouteAttrMapWithRecordNodeResult,
|
|
40
|
+
getRouteAttrMapWithRestNodeResult,
|
|
41
|
+
handleAndReturnResult,
|
|
42
|
+
createRecordCall,
|
|
43
|
+
restTables,
|
|
44
|
+
unHandledIds,
|
|
45
|
+
completelyUnassociatedParamIds,
|
|
46
|
+
potentialRecordCallRouteParams,
|
|
47
|
+
} from './RestUtils'
|
|
48
|
+
import * as z from 'zod'
|
|
49
|
+
import { Diagnostic } from '@servicenow/sdk-project'
|
|
50
|
+
|
|
51
|
+
const methodsAllowedToOverrideRequests = ['PUT', 'PATCH', 'POST']
|
|
52
|
+
const parseAcls = (enforce_acl: EnforceAcl, context: Context) =>
|
|
53
|
+
enforce_acl.map((acl) => (typeof acl === 'string' ? acl : context.keys.registerExplicitId(acl.table, acl.$id)))
|
|
54
|
+
|
|
55
|
+
function restApiAsRecord<I extends number, V extends Version<I>>(config: RestApiConfig<I, V>) {
|
|
56
|
+
const api = RestApiSchema.parse(config)
|
|
57
|
+
return Record({
|
|
58
|
+
table: 'sys_ws_definition',
|
|
59
|
+
$id: api.$id,
|
|
60
|
+
data: {
|
|
61
|
+
active: api.active,
|
|
62
|
+
name: api.name,
|
|
63
|
+
consumes: api.consumes,
|
|
64
|
+
consumes_customized: api.consumes === RestApiSchema.shape.consumes._def.defaultValue() ? false : true,
|
|
65
|
+
produces: api.produces,
|
|
66
|
+
produces_customized: api.produces === RestApiSchema.shape.produces._def.defaultValue() ? false : true,
|
|
67
|
+
default_version: '',
|
|
68
|
+
doc_link: api.doc_link,
|
|
69
|
+
is_versioned: false,
|
|
70
|
+
service_id: api.service_id,
|
|
71
|
+
short_description: api.short_description,
|
|
72
|
+
base_uri: '',
|
|
73
|
+
namespace: '',
|
|
74
|
+
enforce_acl: api.enforce_acl as any,
|
|
75
|
+
...(api.policy && { sys_policy: api.policy }),
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default Plugin({
|
|
81
|
+
name: 'RestApi',
|
|
82
|
+
ownedTables: {
|
|
83
|
+
sys_ws_definition: { diagnosticLevel: Diagnostic.Level.Warn },
|
|
84
|
+
sys_ws_version: { diagnosticLevel: Diagnostic.Level.Warn },
|
|
85
|
+
sys_ws_operation: { diagnosticLevel: Diagnostic.Level.Warn },
|
|
86
|
+
},
|
|
87
|
+
extractors: {
|
|
88
|
+
entity: {
|
|
89
|
+
CallExpression: (node, context) => {
|
|
90
|
+
const result = extractCallExpression(RestApi, 'restApi', node, context, (restApi) =>
|
|
91
|
+
context.registerExplicitId('sys_ws_definition', restApi.$id as string)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if (!result.handled || !(0 in result.data)) {
|
|
95
|
+
return result
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const restAPIEntity = result.data[0]
|
|
99
|
+
const entityData = RestApiSchema.parse(restAPIEntity.getValue())
|
|
100
|
+
const { routes, enforce_acl, consumes, produces } = entityData
|
|
101
|
+
for (const route of routes) {
|
|
102
|
+
const { enforce_acl } = route
|
|
103
|
+
const rawOperationScript = route.script as unknown as ScriptInfo | string
|
|
104
|
+
route.name = route.name ? route.name : route.path
|
|
105
|
+
|
|
106
|
+
if (typeof rawOperationScript !== 'string') {
|
|
107
|
+
const { filePath, functionName, isDefault } = rawOperationScript
|
|
108
|
+
route.script = buildScriptImport(
|
|
109
|
+
filePath,
|
|
110
|
+
functionName,
|
|
111
|
+
isDefault,
|
|
112
|
+
context,
|
|
113
|
+
(funcName: string) => `${funcName}(request, response)\n`
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** allow users to override consumes for allowed http methods*/
|
|
118
|
+
if (
|
|
119
|
+
route.consumes &&
|
|
120
|
+
route.consumes !== consumes &&
|
|
121
|
+
!methodsAllowedToOverrideRequests.includes(route.method)
|
|
122
|
+
) {
|
|
123
|
+
throw Error(`Cannot override consumer type for ${route.method} method`)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
route.consumes = route.consumes ? route.consumes : consumes
|
|
127
|
+
route.produces = route.produces ? route.produces : produces
|
|
128
|
+
route.enforce_acl = parseAcls(enforce_acl, context)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
handled: true,
|
|
133
|
+
diagnostics: result.diagnostics,
|
|
134
|
+
data: [
|
|
135
|
+
new EntityData(
|
|
136
|
+
restAPIEntity.getKind(),
|
|
137
|
+
restAPIEntity.getGuid(),
|
|
138
|
+
ObjectData.fromObjectValue(
|
|
139
|
+
{
|
|
140
|
+
...entityData,
|
|
141
|
+
enforce_acl: parseAcls(enforce_acl, context),
|
|
142
|
+
},
|
|
143
|
+
restAPIEntity.getNode()
|
|
144
|
+
),
|
|
145
|
+
restAPIEntity.getNode()
|
|
146
|
+
),
|
|
147
|
+
],
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
raw: {
|
|
152
|
+
FunctionDeclaration(node, context) {
|
|
153
|
+
const info = scriptInfo(node, context, RestApi.name)
|
|
154
|
+
if (!info) {
|
|
155
|
+
return { handled: false }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return { handled: true, diagnostics: [], data: [info] }
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
FunctionExpression(node, context) {
|
|
162
|
+
const info = scriptInfo(node, context, RestApi.name)
|
|
163
|
+
if (!info) {
|
|
164
|
+
return { handled: false }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return { handled: true, diagnostics: [], data: [info] }
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
composers: {
|
|
172
|
+
entity: {
|
|
173
|
+
restApi(entity, context) {
|
|
174
|
+
const restEntity = entity.getValue()
|
|
175
|
+
const parsedEntity = RestApiSchema.safeParse(restEntity)
|
|
176
|
+
if (!parsedEntity.success) {
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const { routes, versions, enforce_acl } = parsedEntity.data
|
|
181
|
+
const defaultVersions = versions.filter((version) => version.is_default)
|
|
182
|
+
if (defaultVersions.length > 1) {
|
|
183
|
+
throw Error(`Multiple versions cannot be set to default.`)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const {
|
|
187
|
+
app: {
|
|
188
|
+
config: { scope },
|
|
189
|
+
},
|
|
190
|
+
} = context
|
|
191
|
+
const restRecord = restApiAsRecord(restEntity as any) as RecordWithLegacyId<'sys_ws_definition'>
|
|
192
|
+
const apiData = { ...restRecord.data }
|
|
193
|
+
|
|
194
|
+
apiData.base_uri = `/api/${scope}/${apiData.service_id}`
|
|
195
|
+
apiData.namespace = scope
|
|
196
|
+
apiData.default_version =
|
|
197
|
+
defaultVersions.length > 0 ? `v${defaultVersions[0]!.version}` : 'No active default version'
|
|
198
|
+
apiData.enforce_acl = mergeACLIds(enforce_acl) as any
|
|
199
|
+
apiData.is_versioned = versions.length > 0 ? true : false
|
|
200
|
+
|
|
201
|
+
/** generates sys_ws_definition record */
|
|
202
|
+
const updatedRestRecord = Record({
|
|
203
|
+
table: 'sys_ws_definition',
|
|
204
|
+
$id: entity.getGuid(),
|
|
205
|
+
data: apiData,
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
/** generates the sys_ws_version record */
|
|
209
|
+
const versionRecordsAndMap = generateVersionRecords(
|
|
210
|
+
context,
|
|
211
|
+
apiData.default_version,
|
|
212
|
+
versions,
|
|
213
|
+
updatedRestRecord
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
/** generates the sys_ws_operation, sys_ws_header, sys_ws_header_map, sys_ws_query_paramter, sys_ws_query_parameter_map records */
|
|
217
|
+
const routesAndRouteAttrRecords = generateRoutesAndRouteAttrRecords(
|
|
218
|
+
context,
|
|
219
|
+
restRecord.$id,
|
|
220
|
+
routes,
|
|
221
|
+
apiData,
|
|
222
|
+
updatedRestRecord,
|
|
223
|
+
versionRecordsAndMap.mapping
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
return context.composeEntities(
|
|
227
|
+
[updatedRestRecord, ...versionRecordsAndMap.records, ...routesAndRouteAttrRecords].map(
|
|
228
|
+
(r) =>
|
|
229
|
+
new EntityData(
|
|
230
|
+
'record',
|
|
231
|
+
r.$id as string,
|
|
232
|
+
ObjectData.fromObjectValue(r, entity.getNode()),
|
|
233
|
+
entity.getNode()
|
|
234
|
+
)
|
|
235
|
+
),
|
|
236
|
+
[RecordPlugin]
|
|
237
|
+
)
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
arrangers: {
|
|
242
|
+
record(document, context) {
|
|
243
|
+
const table = document.data!['table']
|
|
244
|
+
/** skipping arrangers while serializing as we don't care about the order here. */
|
|
245
|
+
if (!restTables.includes(table) || context.mode === 'serialize') {
|
|
246
|
+
return { handled: false }
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** generates rest document map and validates the params and their mapping records */
|
|
250
|
+
const restDocMap = getRestDocumentMap(context)
|
|
251
|
+
switch (table) {
|
|
252
|
+
case 'sys_ws_operation':
|
|
253
|
+
case 'sys_ws_version':
|
|
254
|
+
return {
|
|
255
|
+
handled: true,
|
|
256
|
+
result: { kind: 'record', guid: document.data!['data']['web_service_definition'] },
|
|
257
|
+
}
|
|
258
|
+
case 'sys_ws_header':
|
|
259
|
+
case 'sys_ws_query_parameter':
|
|
260
|
+
if (!document.node) {
|
|
261
|
+
/** handles case where the incoming xml doesn't have any node associated with it. */
|
|
262
|
+
return handleAndReturnResult(getRouteAttrResult(document, restDocMap), document)
|
|
263
|
+
} else {
|
|
264
|
+
const docNode = document.node as ts.CallExpression
|
|
265
|
+
if (getCallExpressionName(docNode) === Record.name) {
|
|
266
|
+
/** handles case where the incoming xml is currently associated with record call */
|
|
267
|
+
return handleAndReturnResult(
|
|
268
|
+
getRouteAttrWithRecordNodeResult(document, context, restDocMap),
|
|
269
|
+
document
|
|
270
|
+
)
|
|
271
|
+
} else {
|
|
272
|
+
/** handles case where the incoming xml is currently associated with rest call */
|
|
273
|
+
return handleAndReturnResult(
|
|
274
|
+
getRouteAttrWithRestNodeResult(document, context, restDocMap),
|
|
275
|
+
document
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
case 'sys_ws_header_map':
|
|
280
|
+
case 'sys_ws_query_parameter_map':
|
|
281
|
+
if (!document.node) {
|
|
282
|
+
/** handles case where the incoming xml doesn't have any node associated with it. */
|
|
283
|
+
return handleAndReturnResult(getRouteAttrMapResult(document, restDocMap), document)
|
|
284
|
+
} else {
|
|
285
|
+
const docNode = document.node as ts.CallExpression
|
|
286
|
+
if (getCallExpressionName(docNode) === Record.name) {
|
|
287
|
+
/** handles case where the incoming xml is currently associated with record call */
|
|
288
|
+
return handleAndReturnResult(
|
|
289
|
+
getRouteAttrMapWithRecordNodeResult(document, context, restDocMap),
|
|
290
|
+
document
|
|
291
|
+
)
|
|
292
|
+
} else {
|
|
293
|
+
/** handles case where the incoming xml is currently associated with rest call */
|
|
294
|
+
return handleAndReturnResult(
|
|
295
|
+
getRouteAttrMapWithRestNodeResult(document, context, restDocMap),
|
|
296
|
+
document
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
default:
|
|
301
|
+
return { handled: true, result: undefined }
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
generators: {
|
|
306
|
+
record(document, context, linkedDocuments) {
|
|
307
|
+
const table = document.data!['table']
|
|
308
|
+
/**
|
|
309
|
+
* Edge case: m2m record maps non-app rest causing you to unassociate the only associated
|
|
310
|
+
* param record to rest. May require creation of record call for unassociated param if not consumed
|
|
311
|
+
* by any
|
|
312
|
+
*/
|
|
313
|
+
completelyUnassociatedParamIds.forEach((id) => {
|
|
314
|
+
if (potentialRecordCallRouteParams.has(id)) {
|
|
315
|
+
createRecordCall(id, context)
|
|
316
|
+
potentialRecordCallRouteParams.delete(id)
|
|
317
|
+
}
|
|
318
|
+
})
|
|
319
|
+
completelyUnassociatedParamIds.clear()
|
|
320
|
+
/** unHandledIds contains rest record ids for which we need to create record call */
|
|
321
|
+
if (!restTables.includes(table) || unHandledIds.includes(document.guid)) {
|
|
322
|
+
return undefined
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
switch (table) {
|
|
326
|
+
case 'sys_ws_definition':
|
|
327
|
+
// eslint-disable-next-line no-case-declarations
|
|
328
|
+
const linkedDoc = linkDocument(
|
|
329
|
+
document,
|
|
330
|
+
generateCallExpressionExportForDocument(
|
|
331
|
+
context,
|
|
332
|
+
{
|
|
333
|
+
sourceFile: getOrCreateEntitySourceFile(
|
|
334
|
+
context,
|
|
335
|
+
getSysUpdateName(document, 'sys_ws_definition')
|
|
336
|
+
),
|
|
337
|
+
moduleSpecifier: '@servicenow/sdk/core',
|
|
338
|
+
},
|
|
339
|
+
RestApi,
|
|
340
|
+
{}
|
|
341
|
+
).getExpressionIfKindOrThrow(ts.SyntaxKind.CallExpression)
|
|
342
|
+
)
|
|
343
|
+
return linkedDoc
|
|
344
|
+
case 'sys_ws_operation':
|
|
345
|
+
case 'sys_ws_version':
|
|
346
|
+
case 'sys_ws_header':
|
|
347
|
+
case 'sys_ws_query_parameter':
|
|
348
|
+
// eslint-disable-next-line no-case-declarations
|
|
349
|
+
const restDef = linkedDocuments.find(
|
|
350
|
+
(doc) =>
|
|
351
|
+
(doc.data as any).table === 'sys_ws_definition' &&
|
|
352
|
+
doc.guid === (document.data as any).data.web_service_definition
|
|
353
|
+
)
|
|
354
|
+
// eslint-disable-next-line no-case-declarations
|
|
355
|
+
const o_v_node = document.parent!.node ? document.parent!.node : restDef?.node
|
|
356
|
+
if (!o_v_node) {
|
|
357
|
+
return undefined
|
|
358
|
+
}
|
|
359
|
+
return linkDocument(document, o_v_node as ts.CallExpression<ts.ts.CallExpression>)
|
|
360
|
+
case 'sys_ws_header_map':
|
|
361
|
+
case 'sys_ws_query_parameter_map':
|
|
362
|
+
// eslint-disable-next-line no-case-declarations
|
|
363
|
+
const operationDef = linkedDocuments.find(
|
|
364
|
+
(doc) =>
|
|
365
|
+
(doc.data as any).table === 'sys_ws_operation' &&
|
|
366
|
+
doc.guid === (document.data as any).data.web_service_operation
|
|
367
|
+
)
|
|
368
|
+
// eslint-disable-next-line no-case-declarations
|
|
369
|
+
const h_q_node = document.parent?.node ? document.parent?.node : operationDef?.node
|
|
370
|
+
if (!h_q_node) {
|
|
371
|
+
return undefined
|
|
372
|
+
}
|
|
373
|
+
return linkDocument(document, h_q_node as ts.CallExpression<ts.ts.CallExpression>)
|
|
374
|
+
}
|
|
375
|
+
return undefined
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
transformers: {
|
|
379
|
+
record: {
|
|
380
|
+
CallExpression(document, context) {
|
|
381
|
+
if (!shouldHandle(document)) {
|
|
382
|
+
return false
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const documentMap = context.getDocumentMap()
|
|
386
|
+
const table = document.data!['table']
|
|
387
|
+
switch (table) {
|
|
388
|
+
case 'sys_ws_definition':
|
|
389
|
+
return transformDefinition(document, context)
|
|
390
|
+
case 'sys_ws_version':
|
|
391
|
+
return transformRestAttrs(document, context)
|
|
392
|
+
case 'sys_ws_operation':
|
|
393
|
+
return transformRoutes(document, context, documentMap!)
|
|
394
|
+
case 'sys_ws_header':
|
|
395
|
+
return transformRouteAttrs(document, context, 'headers')
|
|
396
|
+
case 'sys_ws_query_parameter':
|
|
397
|
+
return transformRouteAttrs(document, context, 'parameters')
|
|
398
|
+
case 'sys_ws_query_parameter_map':
|
|
399
|
+
return transformRouteAttrsMap(
|
|
400
|
+
document,
|
|
401
|
+
context,
|
|
402
|
+
documentMap!,
|
|
403
|
+
RestRouteQueryMap,
|
|
404
|
+
'parameters',
|
|
405
|
+
(data: z.infer<typeof RestRouteQueryMap>) => {
|
|
406
|
+
return {
|
|
407
|
+
operationId: data.web_service_operation,
|
|
408
|
+
attrId: data.web_service_query_parameter,
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
case 'sys_ws_header_map':
|
|
413
|
+
return transformRouteAttrsMap(
|
|
414
|
+
document,
|
|
415
|
+
context,
|
|
416
|
+
documentMap!,
|
|
417
|
+
RestRouteHeaderMap,
|
|
418
|
+
'headers',
|
|
419
|
+
(data: z.infer<typeof RestRouteHeaderMap>) => {
|
|
420
|
+
return { operationId: data.web_service_operation, attrId: data.web_service_header }
|
|
421
|
+
}
|
|
422
|
+
)
|
|
423
|
+
}
|
|
424
|
+
return false
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
function shouldHandle(document: Document): boolean {
|
|
431
|
+
const docNode = document.node as ts.CallExpression
|
|
432
|
+
return !docNode.wasForgotten() &&
|
|
433
|
+
getCallExpressionName(docNode) === RestApi.name &&
|
|
434
|
+
document.data!['table'] &&
|
|
435
|
+
docNode.getArguments()[0]
|
|
436
|
+
? true
|
|
437
|
+
: false
|
|
438
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseRestApiSchema,
|
|
3
|
+
BaseRouteSchema,
|
|
4
|
+
RouteAttributeSchema,
|
|
5
|
+
VersionSchema,
|
|
6
|
+
} from '@servicenow/sdk-core/runtime/rest'
|
|
7
|
+
import { z } from 'zod'
|
|
8
|
+
|
|
9
|
+
export const RestRouteHeaderMap = z.object({
|
|
10
|
+
web_service_operation: z.string(),
|
|
11
|
+
web_service_header: z.string(),
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export const RestRouteQueryMap = z.object({
|
|
15
|
+
web_service_operation: z.string(),
|
|
16
|
+
web_service_query_parameter: z.string(),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export const RouteAttrWithOutIdSchema = RouteAttributeSchema.omit({ $id: true })
|
|
20
|
+
|
|
21
|
+
export const VersionWithOutIdSchema = VersionSchema.omit({ $id: true })
|
|
22
|
+
|
|
23
|
+
const RestDefinitionSchema = BaseRestApiSchema.omit({ $id: true }).extend({
|
|
24
|
+
enforce_acl: z.string().default(''),
|
|
25
|
+
sys_policy: z.enum(['', 'read', 'protected']).default(''),
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export const RestDefinitionTransformer = RestDefinitionSchema.partial().transform((data) => {
|
|
29
|
+
const { sys_policy, enforce_acl, ...rest } = data
|
|
30
|
+
return {
|
|
31
|
+
...rest,
|
|
32
|
+
...(enforce_acl !== undefined && { enforce_acl: enforce_acl ? enforce_acl.split(',') : [] }),
|
|
33
|
+
...(sys_policy && { policy: sys_policy }),
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const RestRouteSchema = BaseRouteSchema.omit({ $id: true }).extend({
|
|
38
|
+
operation_script: z.string().default(''),
|
|
39
|
+
http_method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).default('GET'),
|
|
40
|
+
relative_path: z.string().default('/'),
|
|
41
|
+
requires_acl_authorization: z.boolean().default(true),
|
|
42
|
+
requires_authentication: z.boolean().default(true),
|
|
43
|
+
requires_snc_internal_role: z.boolean().default(true),
|
|
44
|
+
sys_policy: z.enum(['', 'read', 'protected']).default(''),
|
|
45
|
+
enforce_acl: z.string().default(''),
|
|
46
|
+
web_service_version: z.string().default(''),
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
export const RestRouteTransformer = RestRouteSchema.partial().transform((data) => {
|
|
50
|
+
const {
|
|
51
|
+
operation_script,
|
|
52
|
+
http_method,
|
|
53
|
+
relative_path,
|
|
54
|
+
requires_acl_authorization,
|
|
55
|
+
requires_authentication,
|
|
56
|
+
requires_snc_internal_role,
|
|
57
|
+
sys_policy,
|
|
58
|
+
enforce_acl,
|
|
59
|
+
...rest
|
|
60
|
+
} = data
|
|
61
|
+
return {
|
|
62
|
+
...rest,
|
|
63
|
+
...(enforce_acl !== undefined && { enforce_acl: enforce_acl ? enforce_acl.split(',') : [] }),
|
|
64
|
+
...(operation_script !== undefined && { script: operation_script }),
|
|
65
|
+
...(http_method && { method: http_method }),
|
|
66
|
+
...(relative_path && { path: relative_path }),
|
|
67
|
+
...(requires_acl_authorization !== undefined && { authorization: requires_acl_authorization }),
|
|
68
|
+
...(requires_authentication !== undefined && { authentication: requires_authentication }),
|
|
69
|
+
...(requires_snc_internal_role !== undefined && { internalRole: requires_snc_internal_role }),
|
|
70
|
+
...(sys_policy && { policy: sys_policy }),
|
|
71
|
+
}
|
|
72
|
+
})
|