@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
package/src/db/index.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from './db'
|
|
2
|
+
export * from './uxf'
|
|
3
|
+
export * from './atf'
|
|
4
|
+
export { default as DefaultPlugin } from './DefaultPlugin'
|
|
5
|
+
export { default as ApplicationMenuPlugin } from './app/ApplicationMenuPlugin'
|
|
6
|
+
export { default as PropertyPlugin } from './PropertyPlugin'
|
|
7
|
+
export { default as RestApiPlugin } from './scriptedRESTAPI/RestApiPlugin'
|
|
8
|
+
export { default as UserPreferencePlugin } from './UserPreferencePlugin'
|
|
9
|
+
export { default as CrossScopePrivilegePlugin } from './CrossScopePrivilegePlugin'
|
|
10
|
+
export { default as ClientScriptPlugin } from './scripts/ClientScriptPlugin'
|
|
11
|
+
export { default as BusinessRulePlugin } from './BusinessRulePlugin'
|
|
12
|
+
export { default as ListPluginPlugin } from './ListPlugin'
|
|
13
|
+
export { default as RolePlugin } from './aclAndRole/RolePlugin'
|
|
14
|
+
export { default as AclPlugin } from './aclAndRole/AclPlugin'
|
|
15
|
+
export { default as ScriptTemplatePlugin, UNIQUE_SCRIPT_FILES } from './ScriptTemplatePlugin'
|
|
16
|
+
export { default as IdPlugin } from './IdPlugin'
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Document,
|
|
3
|
+
getOrCreatePropertyAssignment,
|
|
4
|
+
mergeDataIntoObjectLiteral,
|
|
5
|
+
stringify,
|
|
6
|
+
Context,
|
|
7
|
+
DocumentMap,
|
|
8
|
+
removeNode,
|
|
9
|
+
getCallExpressionName,
|
|
10
|
+
getNodeId,
|
|
11
|
+
ArrayIterator,
|
|
12
|
+
} from '@servicenow/sdk-build-core'
|
|
13
|
+
import { RouteSchema, RestApiSchema } from '@servicenow/sdk-core/runtime/rest'
|
|
14
|
+
import * as ts from 'ts-morph'
|
|
15
|
+
import * as z from 'zod'
|
|
16
|
+
import { SyntaxKind } from 'ts-morph'
|
|
17
|
+
import { processScript } from '../ScriptTemplatePlugin'
|
|
18
|
+
import {
|
|
19
|
+
RestDefinitionTransformer,
|
|
20
|
+
VersionWithOutIdSchema,
|
|
21
|
+
RouteAttrWithOutIdSchema,
|
|
22
|
+
RestRouteTransformer,
|
|
23
|
+
} from './RestSchemaUtils'
|
|
24
|
+
import { getArgs, potentialRecordCallRouteParams, isParamAssociated, createRecordCall } from './RestUtils'
|
|
25
|
+
import { Record } from '@servicenow/sdk-core/runtime/db'
|
|
26
|
+
import { isEqual } from 'lodash'
|
|
27
|
+
|
|
28
|
+
function transformId(
|
|
29
|
+
arg: ts.ObjectLiteralExpression,
|
|
30
|
+
argName: string,
|
|
31
|
+
argValue: string,
|
|
32
|
+
tableName: string,
|
|
33
|
+
context: Context
|
|
34
|
+
) {
|
|
35
|
+
if (!arg.getProperty(argName)) {
|
|
36
|
+
const generatedKey = context.keys.getNextAvailableExplicitKey()
|
|
37
|
+
getOrCreatePropertyAssignment(arg, argName, stringify(generatedKey))
|
|
38
|
+
return context.keys.registerExplicitId(tableName, generatedKey, argValue)
|
|
39
|
+
}
|
|
40
|
+
return undefined
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function transformDefinition(document: Document, context: Context) {
|
|
44
|
+
if (document.action === 'DELETE') {
|
|
45
|
+
removeNode(document.node!)
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
48
|
+
const changedData = document.changedData ? document.changedData!['data'] : {}
|
|
49
|
+
const { enforce_acl, ...rest } = RestDefinitionTransformer.parse(changedData)
|
|
50
|
+
const restArgs = getArgs(document)
|
|
51
|
+
cleanUpDefault(RestApiSchema, rest, restArgs)
|
|
52
|
+
transformId(restArgs, '$id', document.guid, 'sys_ws_definition', context)
|
|
53
|
+
transformEnforceAcl(restArgs, enforce_acl, context)
|
|
54
|
+
mergeDataIntoObjectLiteral(restArgs, rest)
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function transformEnforceAcl(args: ts.ObjectLiteralExpression, enforce_acl: string[] | undefined, context: Context) {
|
|
59
|
+
if (enforce_acl === undefined) {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
if (enforce_acl.length === 0) {
|
|
63
|
+
args.getProperty('enforce_acl')?.remove()
|
|
64
|
+
args.addPropertyAssignment({ name: 'enforce_acl', initializer: '[]' })
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
const enforceAclArg = getOrCreatePropertyAssignment(args, 'enforce_acl', '[]')
|
|
68
|
+
const aclIdSet = new Set(enforce_acl)
|
|
69
|
+
const enforceAclIterator = new ArrayIterator(enforceAclArg)
|
|
70
|
+
while (enforceAclIterator.hasNext()) {
|
|
71
|
+
const aclElement = enforceAclIterator.next()
|
|
72
|
+
let aclSysId: string | undefined = undefined
|
|
73
|
+
if (aclElement.isKind(SyntaxKind.StringLiteral)) {
|
|
74
|
+
aclSysId = aclElement.getLiteralValue()
|
|
75
|
+
} else {
|
|
76
|
+
const varDec = (aclElement.getSymbol()?.getValueDeclaration() ??
|
|
77
|
+
aclElement.getSymbol()?.getAliasedSymbol()?.getValueDeclaration()) as ts.VariableDeclaration
|
|
78
|
+
if (varDec) {
|
|
79
|
+
const nodeID = getNodeId(
|
|
80
|
+
varDec
|
|
81
|
+
.getInitializerIfKind(SyntaxKind.CallExpression)
|
|
82
|
+
?.getArguments()[0] as ts.ObjectLiteralExpression
|
|
83
|
+
)!
|
|
84
|
+
aclSysId = context.keys.explicit[nodeID]?.id
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (aclSysId && aclIdSet.has(aclSysId)) {
|
|
89
|
+
aclIdSet.delete(aclSysId)
|
|
90
|
+
} else {
|
|
91
|
+
enforceAclIterator.getExpression().removeElement(aclElement)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (aclIdSet.size > 0) {
|
|
96
|
+
aclIdSet.forEach((id) => {
|
|
97
|
+
enforceAclIterator.getExpression().addElement(stringify(id))
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function transformRestAttrs(document: Document, context: Context) {
|
|
103
|
+
const restArgsNode = getArgs(document)
|
|
104
|
+
const changedData = document.changedData ? document.changedData!['data'] : {}
|
|
105
|
+
const schemaResult = VersionWithOutIdSchema.partial().safeParse(changedData)
|
|
106
|
+
if (!schemaResult.success) {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const restAttrArrayNode = getOrCreatePropertyAssignment(restArgsNode, 'versions', '[]')
|
|
111
|
+
const cData = schemaResult.data
|
|
112
|
+
const versionArrayIterator = new ArrayIterator(restAttrArrayNode)
|
|
113
|
+
const expression = versionArrayIterator.getExpression()
|
|
114
|
+
let isHandled = false
|
|
115
|
+
while (versionArrayIterator.hasNext() && !isHandled) {
|
|
116
|
+
const element = versionArrayIterator.next()
|
|
117
|
+
const verId = getNodeId(element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression))!
|
|
118
|
+
const verSysId = context.keys.explicit[verId]?.id
|
|
119
|
+
if (verSysId === document.guid) {
|
|
120
|
+
if (document.action === 'DELETE') {
|
|
121
|
+
expression.removeElement(element)
|
|
122
|
+
} else {
|
|
123
|
+
const eleObj = element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
124
|
+
cleanUpDefault(VersionWithOutIdSchema, cData, eleObj)
|
|
125
|
+
mergeDataIntoObjectLiteral(eleObj, cData)
|
|
126
|
+
}
|
|
127
|
+
isHandled = true
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!isHandled && document.action !== 'DELETE') {
|
|
131
|
+
cleanUpDefault(VersionWithOutIdSchema, cData)
|
|
132
|
+
const element = expression.addElement(stringify(cData)).asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
133
|
+
transformId(element, '$id', document.guid, 'sys_ws_version', context)
|
|
134
|
+
return true
|
|
135
|
+
}
|
|
136
|
+
return isHandled
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function transformRouteAttrs(document: Document, context: Context, argName: string) {
|
|
140
|
+
const restArgsNode = getArgs(document)
|
|
141
|
+
const changedData = document.changedData ? document.changedData!['data'] : {}
|
|
142
|
+
const routeAttr = RouteAttrWithOutIdSchema.partial().safeParse(changedData)
|
|
143
|
+
if (!routeAttr.success) {
|
|
144
|
+
return false
|
|
145
|
+
}
|
|
146
|
+
const routeAttrData = routeAttr.data
|
|
147
|
+
const routesArrayNode = getOrCreatePropertyAssignment(restArgsNode, 'routes', '[]')
|
|
148
|
+
const routeArrayIterator = new ArrayIterator(routesArrayNode)
|
|
149
|
+
while (routeArrayIterator.hasNext()) {
|
|
150
|
+
const element = routeArrayIterator.next()
|
|
151
|
+
const routeAttrsNode = getOrCreatePropertyAssignment(
|
|
152
|
+
element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression),
|
|
153
|
+
argName,
|
|
154
|
+
'[]'
|
|
155
|
+
)
|
|
156
|
+
const routeAttrIterator = new ArrayIterator(routeAttrsNode)
|
|
157
|
+
const arrayExpression = routeArrayIterator.getExpression()
|
|
158
|
+
while (routeAttrIterator.hasNext()) {
|
|
159
|
+
const attrElement = routeAttrIterator.next()
|
|
160
|
+
const attrId = getNodeId(attrElement.asKindOrThrow(SyntaxKind.ObjectLiteralExpression))
|
|
161
|
+
const attrSysId = context.keys.explicit[attrId!]?.id
|
|
162
|
+
if (attrSysId === document.guid) {
|
|
163
|
+
if (document.action === 'DELETE') {
|
|
164
|
+
arrayExpression.removeElement(element)
|
|
165
|
+
} else {
|
|
166
|
+
const attrEleObj = attrElement.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
167
|
+
cleanUpDefault(RouteAttrWithOutIdSchema, routeAttrData, attrEleObj)
|
|
168
|
+
mergeDataIntoObjectLiteral(attrEleObj, routeAttrData)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return true
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const getDocument = (documentId: string, kind: string, docMap: DocumentMap) => {
|
|
177
|
+
if (!docMap[kind] || !docMap[kind]![documentId]) {
|
|
178
|
+
throw new Error(`Unable to find ${kind} with sysId: ${documentId}`)
|
|
179
|
+
}
|
|
180
|
+
return docMap[kind]![documentId]!
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function getDefaults<Schema extends z.AnyZodObject>(schema: Schema) {
|
|
184
|
+
return Object.fromEntries(
|
|
185
|
+
Object.entries(schema.shape).map(([key, value]) => {
|
|
186
|
+
if (value instanceof z.ZodDefault) {
|
|
187
|
+
return [key, value._def.defaultValue()]
|
|
188
|
+
}
|
|
189
|
+
return [key, undefined]
|
|
190
|
+
})
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function cleanUpDefault<Schema extends z.AnyZodObject>(
|
|
195
|
+
schema: Schema,
|
|
196
|
+
targetObj: any,
|
|
197
|
+
node?: ts.ObjectLiteralExpression
|
|
198
|
+
) {
|
|
199
|
+
const defaults = getDefaults(schema)
|
|
200
|
+
Object.entries(targetObj).forEach(([key, value]) => {
|
|
201
|
+
const removeDef = node ? !node.getProperty(key) : true
|
|
202
|
+
if (defaults[key] !== undefined && defaults[key] === value && removeDef) {
|
|
203
|
+
delete targetObj[key]
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function transformRoutes(document: Document, context: Context, documentMap: DocumentMap) {
|
|
209
|
+
const restArgsNode = getArgs(document)
|
|
210
|
+
const changedData = document.changedData ? document.changedData!['data'] : {}
|
|
211
|
+
const transformedRouteResp = RestRouteTransformer.safeParse(changedData)
|
|
212
|
+
if (!transformedRouteResp.success) {
|
|
213
|
+
return false
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const rawRouteData = transformedRouteResp.data
|
|
217
|
+
const { script, web_service_version, enforce_acl, ...rest } = rawRouteData
|
|
218
|
+
let version: number | undefined = undefined
|
|
219
|
+
if (web_service_version) {
|
|
220
|
+
version = getDocument(web_service_version, 'record', documentMap).data!['data']['version'] as number
|
|
221
|
+
}
|
|
222
|
+
const parsedRouteData = {
|
|
223
|
+
...rest,
|
|
224
|
+
...(version && { version }),
|
|
225
|
+
}
|
|
226
|
+
const routesArrayNode = getOrCreatePropertyAssignment(restArgsNode, 'routes', '[]')
|
|
227
|
+
const routeArrayIterator = new ArrayIterator(routesArrayNode)
|
|
228
|
+
const expression = routeArrayIterator.getExpression()
|
|
229
|
+
let isHandled = false
|
|
230
|
+
while (routeArrayIterator.hasNext() && !isHandled) {
|
|
231
|
+
const element = routeArrayIterator.next()
|
|
232
|
+
const routeId = getNodeId(element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression))!
|
|
233
|
+
const routeSysId = context.keys.explicit[routeId]?.id
|
|
234
|
+
if (routeSysId === document.guid) {
|
|
235
|
+
if (document.action === 'DELETE') {
|
|
236
|
+
expression.removeElement(element)
|
|
237
|
+
} else {
|
|
238
|
+
const eleObj = element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
239
|
+
transformEnforceAcl(eleObj, enforce_acl, context)
|
|
240
|
+
if (script !== undefined) {
|
|
241
|
+
processScript(eleObj, 'script', script, document.guid, 'sys_ws_operation', context)
|
|
242
|
+
}
|
|
243
|
+
cleanUpDefault(RouteSchema, parsedRouteData, eleObj)
|
|
244
|
+
mergeDataIntoObjectLiteral(eleObj, parsedRouteData)
|
|
245
|
+
}
|
|
246
|
+
isHandled = true
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!isHandled && document.action !== 'DELETE') {
|
|
251
|
+
cleanUpDefault(RouteSchema, parsedRouteData)
|
|
252
|
+
const element = expression
|
|
253
|
+
.addElement(stringify(parsedRouteData))
|
|
254
|
+
.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
255
|
+
transformEnforceAcl(element, enforce_acl, context)
|
|
256
|
+
if (script !== undefined) {
|
|
257
|
+
processScript(element, 'script', script, document.guid, 'sys_ws_operation', context)
|
|
258
|
+
}
|
|
259
|
+
transformId(element, '$id', document.guid, 'sys_ws_operation', context)
|
|
260
|
+
return true
|
|
261
|
+
}
|
|
262
|
+
return isHandled
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function transformRouteAttrsMap<T>(
|
|
266
|
+
document: Document,
|
|
267
|
+
context: Context,
|
|
268
|
+
documentMap: DocumentMap,
|
|
269
|
+
routeAttrSchema: z.ZodSchema<T>,
|
|
270
|
+
argName: string,
|
|
271
|
+
callback: (data: T) => { operationId: string; attrId: string }
|
|
272
|
+
) {
|
|
273
|
+
const restArgsNode = getArgs(document)
|
|
274
|
+
const restId = getNodeId(restArgsNode)
|
|
275
|
+
const routeAttrSchemaResp = routeAttrSchema.safeParse(document.data!['data'])
|
|
276
|
+
if (!routeAttrSchemaResp.success) {
|
|
277
|
+
return false
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** To handle scenario where the mapping record initially was mapping route1 to parameter1 has changed
|
|
281
|
+
* to route2 to parameter1 within the same rest api. We remove the old reference and its keys and update the new one.
|
|
282
|
+
* This also helps in case of delete action, where the user modified the route before delete and performed the delete action.
|
|
283
|
+
*/
|
|
284
|
+
const idx = context.keys.composite.findIndex((k) => k.id === document.guid)
|
|
285
|
+
const routeKey = idx !== -1 ? context.keys.composite[idx]!.key['route'] : undefined
|
|
286
|
+
const routeId = routeKey ? context.keys.explicit[routeKey]?.id : undefined
|
|
287
|
+
const { attrId, operationId } = callback(routeAttrSchemaResp.data)
|
|
288
|
+
let deletedParamID: string | undefined = undefined
|
|
289
|
+
let removedAttrId: string | undefined = undefined
|
|
290
|
+
let removalKey: { attr: string; route: string; rest: string } | undefined = undefined
|
|
291
|
+
if (routeId && operationId !== routeId) {
|
|
292
|
+
removalKey = context.keys.composite[idx]!.key as { route: string; attr: string; rest: string }
|
|
293
|
+
context.keys.composite.splice(idx, 1)
|
|
294
|
+
removedAttrId = context.keys.explicit[removalKey?.attr]?.id
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let parsedAttrData = {}
|
|
298
|
+
if (document.action !== 'DELETE') {
|
|
299
|
+
const attrDoc = getDocument(attrId, 'record', documentMap)
|
|
300
|
+
/**
|
|
301
|
+
* Case where the only transformed doc is mapping record and the referenced parameter or header is associated to a record call.
|
|
302
|
+
* Remove the record call and associated key and consume it with the rest.
|
|
303
|
+
*/
|
|
304
|
+
if (
|
|
305
|
+
attrDoc.node &&
|
|
306
|
+
!attrDoc.node.wasForgotten() &&
|
|
307
|
+
getCallExpressionName(attrDoc.node as ts.CallExpression) === Record.name
|
|
308
|
+
) {
|
|
309
|
+
const attrId = getNodeId(getArgs(attrDoc))!
|
|
310
|
+
removeNode(attrDoc.node)
|
|
311
|
+
delete context.keys.explicit[attrId]
|
|
312
|
+
}
|
|
313
|
+
const attrInfo = attrDoc.data!['data']
|
|
314
|
+
const parsedRestAttr = RouteAttrWithOutIdSchema.safeParse(attrInfo)
|
|
315
|
+
|
|
316
|
+
if (!parsedRestAttr.success) {
|
|
317
|
+
return false
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
parsedAttrData = parsedRestAttr.data
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const routesArrayNode = getOrCreatePropertyAssignment(restArgsNode, 'routes', '[]')
|
|
324
|
+
const routeArrayIterator = new ArrayIterator(routesArrayNode)
|
|
325
|
+
while (routeArrayIterator.hasNext()) {
|
|
326
|
+
const element = routeArrayIterator.next()
|
|
327
|
+
const routeId = getNodeId(element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression))!
|
|
328
|
+
const routeSysId = context.keys.explicit[routeId]?.id
|
|
329
|
+
if (routeSysId === operationId || (removalKey && removalKey.route === routeId)) {
|
|
330
|
+
const routeAttrsNode = getOrCreatePropertyAssignment(
|
|
331
|
+
element.asKindOrThrow(SyntaxKind.ObjectLiteralExpression),
|
|
332
|
+
argName,
|
|
333
|
+
'[]'
|
|
334
|
+
)
|
|
335
|
+
const routeAttrIterator = new ArrayIterator(routeAttrsNode)
|
|
336
|
+
const attrExpression = routeAttrIterator.getExpression()
|
|
337
|
+
let isHandled = false
|
|
338
|
+
while (routeAttrIterator.hasNext()) {
|
|
339
|
+
const attrElement = routeAttrIterator.next()
|
|
340
|
+
const attrNodeId = getNodeId(attrElement.asKindOrThrow(SyntaxKind.ObjectLiteralExpression))
|
|
341
|
+
const attrMapId = context.keys.composite.find((k) =>
|
|
342
|
+
isEqual(k.key, {
|
|
343
|
+
attr: attrNodeId!,
|
|
344
|
+
route: routeId!,
|
|
345
|
+
rest: restId!,
|
|
346
|
+
})
|
|
347
|
+
)?.id
|
|
348
|
+
if (removalKey && removalKey.attr === attrNodeId) {
|
|
349
|
+
deletedParamID = removedAttrId
|
|
350
|
+
attrExpression.removeElement(attrElement)
|
|
351
|
+
}
|
|
352
|
+
if (attrMapId === document.guid && routeSysId === operationId) {
|
|
353
|
+
if (document.action === 'DELETE') {
|
|
354
|
+
deletedParamID = attrId
|
|
355
|
+
attrExpression.removeElement(attrElement)
|
|
356
|
+
} else {
|
|
357
|
+
const attrEleObj = attrElement.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
358
|
+
cleanUpDefault(RouteAttrWithOutIdSchema, parsedAttrData, attrEleObj)
|
|
359
|
+
mergeDataIntoObjectLiteral(attrEleObj, parsedAttrData)
|
|
360
|
+
}
|
|
361
|
+
isHandled = true
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (!isHandled && document.action !== 'DELETE' && routeSysId === operationId) {
|
|
365
|
+
cleanUpDefault(RouteAttrWithOutIdSchema, parsedAttrData)
|
|
366
|
+
const element = attrExpression
|
|
367
|
+
.addElement(stringify(parsedAttrData))
|
|
368
|
+
.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
369
|
+
const table = argName === 'headers' ? 'sys_ws_header' : 'sys_ws_query_parameter'
|
|
370
|
+
const foundAttrId = context.keys.findExplicitKeyById(attrId)
|
|
371
|
+
|
|
372
|
+
let uniqueId: string | undefined = ''
|
|
373
|
+
if (foundAttrId) {
|
|
374
|
+
uniqueId = attrId
|
|
375
|
+
const currentKey = context.keys.findExplicitKeyById(uniqueId!)!
|
|
376
|
+
getOrCreatePropertyAssignment(element, '$id', stringify(currentKey))
|
|
377
|
+
} else {
|
|
378
|
+
uniqueId = transformId(element, '$id', attrId, table, context)
|
|
379
|
+
}
|
|
380
|
+
context.keys.registerCompositeId(
|
|
381
|
+
`${table}_map`,
|
|
382
|
+
{
|
|
383
|
+
attr: context.keys.findExplicitKeyById(uniqueId!)!,
|
|
384
|
+
route: routeId!,
|
|
385
|
+
rest: restId!,
|
|
386
|
+
},
|
|
387
|
+
document.guid
|
|
388
|
+
)
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (deletedParamID) {
|
|
394
|
+
/**
|
|
395
|
+
* Conditions under which record call needs to be generated
|
|
396
|
+
* 1. Check if this mapping record is the last record that associate the param to the rest.
|
|
397
|
+
* 2. Check if its mentioned in potentailIds.
|
|
398
|
+
* If both of the above conditions pass then create a record call, because this param is not consumed
|
|
399
|
+
* anywhere and is going to be permanently removed from the rest.
|
|
400
|
+
*/
|
|
401
|
+
const attrName = document.data!['table'] === 'sys_ws_header_map' ? 'headers' : 'parameters'
|
|
402
|
+
if (
|
|
403
|
+
!isParamAssociated(document, attrName, context, deletedParamID) &&
|
|
404
|
+
potentialRecordCallRouteParams.has(deletedParamID)
|
|
405
|
+
) {
|
|
406
|
+
createRecordCall(deletedParamID, context)
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return true
|
|
410
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { RestApiSchema, RouteAttributes } from '@servicenow/sdk-core/runtime/rest'
|
|
2
|
+
import { Record, Data } from '@servicenow/sdk-core/runtime/db'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import * as _ from 'lodash'
|
|
5
|
+
import { Context } from '@servicenow/sdk-build-core'
|
|
6
|
+
import type { TableName } from '@servicenow/sdk-core/runtime/db'
|
|
7
|
+
|
|
8
|
+
export type Versions = z.infer<typeof RestApiSchema.shape.versions>
|
|
9
|
+
export type Routes = z.infer<typeof RestApiSchema.shape.routes>
|
|
10
|
+
export type EnforceAcl = z.infer<typeof RestApiSchema.shape.enforce_acl>
|
|
11
|
+
type Route = Routes[number]
|
|
12
|
+
|
|
13
|
+
export const mergeACLIds = (acls: any[]) => _.join(acls, ',')
|
|
14
|
+
|
|
15
|
+
export function generateVersionRecords(
|
|
16
|
+
context: Context,
|
|
17
|
+
defaultVersion: string,
|
|
18
|
+
versions: Versions,
|
|
19
|
+
apiRecord: Record<'sys_ws_definition'>
|
|
20
|
+
) {
|
|
21
|
+
const versionsRecords: Record[] = []
|
|
22
|
+
const versionRecordMap: Map<string, Record<'sys_ws_version'>> = new Map()
|
|
23
|
+
|
|
24
|
+
for (const version of versions) {
|
|
25
|
+
const versionId = `v${version.version}`
|
|
26
|
+
const versionRecord = Record({
|
|
27
|
+
table: 'sys_ws_version',
|
|
28
|
+
$id: context.keys.registerExplicitId('sys_ws_version', version.$id),
|
|
29
|
+
data: {
|
|
30
|
+
active: version.active,
|
|
31
|
+
deprecated: version.deprecated,
|
|
32
|
+
is_default: defaultVersion === versionId ? true : false,
|
|
33
|
+
short_description: version.short_description,
|
|
34
|
+
version: version.version,
|
|
35
|
+
version_id: versionId,
|
|
36
|
+
web_service_definition: apiRecord,
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
versionsRecords.push(versionRecord)
|
|
40
|
+
/** versions have to be unique */
|
|
41
|
+
if (versionRecordMap.has(versionId)) {
|
|
42
|
+
throw Error(
|
|
43
|
+
`Found duplicated version: ${version.version} in ${apiRecord.$id}. All versions must be unique.`
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
versionRecordMap.set(versionId, versionRecord)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
records: versionsRecords,
|
|
51
|
+
mapping: versionRecordMap,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function generateRouteAttributesRecords<T extends TableName, M extends TableName>(
|
|
56
|
+
context: Context,
|
|
57
|
+
restId: string | number,
|
|
58
|
+
routeId: string | number,
|
|
59
|
+
attributes: RouteAttributes[],
|
|
60
|
+
collection: T,
|
|
61
|
+
mapping_collection: M,
|
|
62
|
+
attrField: string,
|
|
63
|
+
apiRecord: Record<'sys_ws_definition'>,
|
|
64
|
+
routeRecord: Record<'sys_ws_operation'>,
|
|
65
|
+
recordMap: Map<string, Record>
|
|
66
|
+
) {
|
|
67
|
+
const attributeRecords: Record[] = []
|
|
68
|
+
|
|
69
|
+
for (const attribute of attributes) {
|
|
70
|
+
const attrId = context.keys.registerExplicitId(collection as string, attribute.$id)
|
|
71
|
+
const attributeRecord = Record({
|
|
72
|
+
table: collection,
|
|
73
|
+
$id: attrId,
|
|
74
|
+
data: {
|
|
75
|
+
name: attribute.name,
|
|
76
|
+
required: attribute.required,
|
|
77
|
+
short_description: attribute.short_description,
|
|
78
|
+
example_value: attribute.example_value,
|
|
79
|
+
web_service_definition: apiRecord,
|
|
80
|
+
} as Data<T>,
|
|
81
|
+
})
|
|
82
|
+
/**
|
|
83
|
+
* In RestApi since we associate same parameter and headers with multiple routes
|
|
84
|
+
* during serialization we would end up generating duplicated records for headers
|
|
85
|
+
* and parameters. Here we throw error if two duplicated record have different data.
|
|
86
|
+
* Note: two duplicated records would have different data when user refercening a parameter
|
|
87
|
+
* in multiple routes updated in just one place.
|
|
88
|
+
*/
|
|
89
|
+
checkForDuplicateRecords(recordMap, attrId, attributeRecord, attributeRecords)
|
|
90
|
+
|
|
91
|
+
const attrMapId = context.keys.registerCompositeId(mapping_collection as string, {
|
|
92
|
+
attr: attribute.$id,
|
|
93
|
+
route: routeId,
|
|
94
|
+
rest: restId,
|
|
95
|
+
})
|
|
96
|
+
const attrMapRecord = Record({
|
|
97
|
+
table: mapping_collection,
|
|
98
|
+
$id: attrMapId,
|
|
99
|
+
data: {
|
|
100
|
+
web_service_operation: routeRecord,
|
|
101
|
+
[attrField]: attributeRecord,
|
|
102
|
+
} as unknown as Data<M>,
|
|
103
|
+
})
|
|
104
|
+
attributeRecords.push(attrMapRecord)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return attributeRecords
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function checkForDuplicateRecords(
|
|
111
|
+
recordMap: Map<string, Record>,
|
|
112
|
+
recordId: string,
|
|
113
|
+
record: Record,
|
|
114
|
+
attrRecords: Record[]
|
|
115
|
+
) {
|
|
116
|
+
if (!recordMap.has(recordId)) {
|
|
117
|
+
recordMap.set(recordId, record)
|
|
118
|
+
attrRecords.push(record)
|
|
119
|
+
} else {
|
|
120
|
+
const matchRec = recordMap.get(recordId)
|
|
121
|
+
const { web_service_definition: _mwd, ...mRest } = matchRec!.data as any
|
|
122
|
+
const { web_service_definition: _wd, ...rest } = record.data as any
|
|
123
|
+
if (!_.isEqual(rest, mRest)) {
|
|
124
|
+
throw Error(
|
|
125
|
+
`Found duplicate route attribute map records starting with id: ${recordId}, to have conflicting data.`
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function generateRoutesAndRouteAttrRecords(
|
|
132
|
+
context: Context,
|
|
133
|
+
restId: string | number,
|
|
134
|
+
routes: Routes,
|
|
135
|
+
apiData: any,
|
|
136
|
+
apiRecord: Record<'sys_ws_definition'>,
|
|
137
|
+
versionMap: Map<string, Record<'sys_ws_version'>>
|
|
138
|
+
) {
|
|
139
|
+
const routesRecords: Record[] = []
|
|
140
|
+
const headerRecordMap: Map<string, Record> = new Map()
|
|
141
|
+
const paramRecordMap: Map<string, Record> = new Map()
|
|
142
|
+
|
|
143
|
+
for (const route of routes) {
|
|
144
|
+
const routeParameters = route.parameters
|
|
145
|
+
const routeHeaders = route.headers
|
|
146
|
+
const defaultOperationURI = `${apiData.base_uri}${route.path}`
|
|
147
|
+
const baseOperationURI = `/api/${apiData.namespace}`
|
|
148
|
+
const remOperationURI = `${apiData.service_id}${route.path}`
|
|
149
|
+
const operationURI = route.version
|
|
150
|
+
? `${baseOperationURI}/v${route.version}/${remOperationURI}`
|
|
151
|
+
: `${baseOperationURI}/${remOperationURI}`
|
|
152
|
+
|
|
153
|
+
const routeRecord = Record({
|
|
154
|
+
table: 'sys_ws_operation',
|
|
155
|
+
$id: context.keys.registerExplicitId('sys_ws_operation', route.$id),
|
|
156
|
+
data: {
|
|
157
|
+
name: route.name,
|
|
158
|
+
active: route.active,
|
|
159
|
+
consumes: route.consumes,
|
|
160
|
+
consumes_customized: apiData.consumes === route.consumes ? false : true,
|
|
161
|
+
default_operation_uri: `v${route.version}` === apiData.default_version ? defaultOperationURI : '',
|
|
162
|
+
http_method: route.method,
|
|
163
|
+
operation_script: route.script,
|
|
164
|
+
operation_uri: operationURI,
|
|
165
|
+
produces: route.produces,
|
|
166
|
+
produces_customized: apiData.produces === route.produces ? false : true,
|
|
167
|
+
relative_path: route.path,
|
|
168
|
+
enforce_acl: mergeACLIds(route.enforce_acl) as any,
|
|
169
|
+
requires_acl_authorization: route.authorization,
|
|
170
|
+
requires_authentication: route.authentication,
|
|
171
|
+
requires_snc_internal_role: route.internalRole,
|
|
172
|
+
short_description: route.short_description,
|
|
173
|
+
request_example: route.request_example,
|
|
174
|
+
web_service_definition: apiRecord,
|
|
175
|
+
web_service_version: getRestRouteVersion(route, versionMap),
|
|
176
|
+
...(route.policy && { sys_policy: route.policy }),
|
|
177
|
+
},
|
|
178
|
+
})
|
|
179
|
+
routesRecords.push(routeRecord)
|
|
180
|
+
|
|
181
|
+
/** generates the sys_ws_query_parameter and sys_ws_query_parameter_map records */
|
|
182
|
+
const routeParamRecords = generateRouteAttributesRecords(
|
|
183
|
+
context,
|
|
184
|
+
restId,
|
|
185
|
+
route.$id,
|
|
186
|
+
routeParameters,
|
|
187
|
+
'sys_ws_query_parameter',
|
|
188
|
+
'sys_ws_query_parameter_map',
|
|
189
|
+
'web_service_query_parameter',
|
|
190
|
+
apiRecord,
|
|
191
|
+
routeRecord,
|
|
192
|
+
paramRecordMap
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
/** generates the sys_ws_header and sys_ws_header_map records */
|
|
196
|
+
const routeHeaderRecords = generateRouteAttributesRecords(
|
|
197
|
+
context,
|
|
198
|
+
restId,
|
|
199
|
+
route.$id,
|
|
200
|
+
routeHeaders,
|
|
201
|
+
'sys_ws_header',
|
|
202
|
+
'sys_ws_header_map',
|
|
203
|
+
'web_service_header',
|
|
204
|
+
apiRecord,
|
|
205
|
+
routeRecord,
|
|
206
|
+
headerRecordMap
|
|
207
|
+
)
|
|
208
|
+
routesRecords.push(...[...routeParamRecords, ...routeHeaderRecords])
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return routesRecords
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function getRestRouteVersion(route: Route, versionMap: Map<string, Record<'sys_ws_version'>>) {
|
|
215
|
+
/** throws error when a route specifies version not mentioned in versions array of rest*/
|
|
216
|
+
const version = ''
|
|
217
|
+
if (route.version) {
|
|
218
|
+
if (!versionMap.has(`v${route.version}`)) {
|
|
219
|
+
throw Error(
|
|
220
|
+
`Unable to resolve version record for version ${route.version}. Check if the version is listed in your API versions list.`
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
return versionMap.get(`v${route.version}`)!
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return version
|
|
227
|
+
}
|