isc-transforms-mcp 1.0.15 → 1.0.16
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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "sailpoint.isc.transforms.lookup.schema.json",
|
|
4
4
|
"title": "SailPoint ISC Transform Schema - lookup",
|
|
5
|
-
"description": "Strict schema
|
|
5
|
+
"description": "Strict schema for the SailPoint ISC Lookup transform. Maps an incoming string value against a static key-value table and returns the corresponding output. If the input matches a table key, that key's value is returned. If no key matches, the 'default' key's value is returned. IMPORTANT: The 'default' key is mandatory — without it, any unmatched input causes a runtime error. Table comparisons are case-sensitive. Only static string values are supported in the table — nested transforms and conditional logic within table values are not supported.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": [
|
|
@@ -12,16 +12,18 @@
|
|
|
12
12
|
],
|
|
13
13
|
"properties": {
|
|
14
14
|
"type": {
|
|
15
|
-
"const": "lookup"
|
|
15
|
+
"const": "lookup",
|
|
16
|
+
"description": "Transform operation type. Must be exactly 'lookup'."
|
|
16
17
|
},
|
|
17
18
|
"name": {
|
|
18
19
|
"type": "string",
|
|
19
|
-
"minLength": 1
|
|
20
|
+
"minLength": 1,
|
|
21
|
+
"description": "Display name for this transform, shown in UI dropdowns and identity profile mappings."
|
|
20
22
|
},
|
|
21
23
|
"requiresPeriodicRefresh": {
|
|
22
24
|
"type": "boolean",
|
|
23
25
|
"default": false,
|
|
24
|
-
"description": "
|
|
26
|
+
"description": "If true, re-evaluates this transform during the nightly identity refresh cycle. Default is false."
|
|
25
27
|
},
|
|
26
28
|
"attributes": {
|
|
27
29
|
"type": "object",
|
|
@@ -29,21 +31,32 @@
|
|
|
29
31
|
"required": [
|
|
30
32
|
"table"
|
|
31
33
|
],
|
|
34
|
+
"description": "Required container for lookup operation attributes.",
|
|
32
35
|
"properties": {
|
|
33
36
|
"table": {
|
|
34
37
|
"type": "object",
|
|
35
|
-
"description": "
|
|
36
|
-
"additionalProperties": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"description": "Lookup output value."
|
|
39
|
-
},
|
|
38
|
+
"description": "Required key-value mapping object. The key is the string the transform tries to match against the input value; the corresponding string value is returned on a match. MANDATORY: Must include a 'default' key — without it, any input that doesn't match a key causes a runtime error. Rules: (1) All values must be static strings — nested transforms are not supported. (2) Comparisons are case-sensitive: 'US' and 'us' are different keys. (3) Duplicate keys are not permitted. (4) Multiple keys may map to the same output value.",
|
|
40
39
|
"required": [
|
|
41
40
|
"default"
|
|
42
|
-
]
|
|
41
|
+
],
|
|
42
|
+
"properties": {
|
|
43
|
+
"default": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Mandatory fallback value returned when the input does not match any other key in the table. Prevents runtime errors on unmatched input."
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"additionalProperties": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"description": "Output string value returned when the input matches this key. The key is compared case-sensitively against the input value."
|
|
51
|
+
}
|
|
43
52
|
},
|
|
44
53
|
"input": {
|
|
45
|
-
"description": "Optional explicit input
|
|
46
|
-
"
|
|
54
|
+
"description": "Optional explicit input that provides the string value to look up in the table. If omitted, the transform uses the source and attribute combination configured in the identity profile UI. When provided, must be a nested transform object or a static string.",
|
|
55
|
+
"anyOf": [
|
|
56
|
+
{
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "Static string value to use as the lookup key."
|
|
59
|
+
},
|
|
47
60
|
{
|
|
48
61
|
"$ref": "#/$defs/NestedTransform"
|
|
49
62
|
}
|
|
@@ -55,7 +68,7 @@
|
|
|
55
68
|
"$defs": {
|
|
56
69
|
"NestedTransform": {
|
|
57
70
|
"type": "object",
|
|
58
|
-
"description": "
|
|
71
|
+
"description": "A nested transform object that provides the input value to look up. Its output string is matched against the table keys. Common use: accountAttribute or identityAttribute to supply a source value for the lookup. The 'name' field is optional in nested transforms per SailPoint docs.",
|
|
59
72
|
"additionalProperties": false,
|
|
60
73
|
"required": [
|
|
61
74
|
"type",
|
|
@@ -63,18 +76,22 @@
|
|
|
63
76
|
],
|
|
64
77
|
"properties": {
|
|
65
78
|
"id": {
|
|
66
|
-
"type": "string"
|
|
79
|
+
"type": "string",
|
|
80
|
+
"description": "Optional ID when referencing an existing saved transform."
|
|
67
81
|
},
|
|
68
82
|
"name": {
|
|
69
83
|
"type": "string",
|
|
70
|
-
"minLength": 1
|
|
84
|
+
"minLength": 1,
|
|
85
|
+
"description": "Optional display name for the nested transform."
|
|
71
86
|
},
|
|
72
87
|
"type": {
|
|
73
88
|
"type": "string",
|
|
74
|
-
"minLength": 1
|
|
89
|
+
"minLength": 1,
|
|
90
|
+
"description": "The operation type of the nested transform (e.g., 'accountAttribute', 'identityAttribute', 'lower')."
|
|
75
91
|
},
|
|
76
92
|
"requiresPeriodicRefresh": {
|
|
77
|
-
"type": "boolean"
|
|
93
|
+
"type": "boolean",
|
|
94
|
+
"description": "Whether this nested transform re-evaluates during nightly refresh."
|
|
78
95
|
},
|
|
79
96
|
"attributes": {
|
|
80
97
|
"type": "object",
|
|
@@ -86,15 +103,72 @@
|
|
|
86
103
|
},
|
|
87
104
|
"examples": [
|
|
88
105
|
{
|
|
106
|
+
"name": "Country Code to Country Name",
|
|
89
107
|
"type": "lookup",
|
|
90
|
-
"name": "Lookup Transform",
|
|
91
108
|
"attributes": {
|
|
92
109
|
"table": {
|
|
93
110
|
"US": "United States",
|
|
94
111
|
"IN": "India",
|
|
112
|
+
"GB": "United Kingdom",
|
|
113
|
+
"AU": "Australia",
|
|
95
114
|
"default": "Unknown"
|
|
96
115
|
}
|
|
97
116
|
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "Department Code to Building",
|
|
120
|
+
"type": "lookup",
|
|
121
|
+
"attributes": {
|
|
122
|
+
"table": {
|
|
123
|
+
"ENG": "Building A",
|
|
124
|
+
"HR": "Building B",
|
|
125
|
+
"FIN": "Building C",
|
|
126
|
+
"default": "Main Campus"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "Employment Type with Nested Input",
|
|
132
|
+
"type": "lookup",
|
|
133
|
+
"attributes": {
|
|
134
|
+
"table": {
|
|
135
|
+
"FTE": "Full-Time Employee",
|
|
136
|
+
"PTE": "Part-Time Employee",
|
|
137
|
+
"CON": "Contractor",
|
|
138
|
+
"default": "Unknown"
|
|
139
|
+
},
|
|
140
|
+
"input": {
|
|
141
|
+
"type": "accountAttribute",
|
|
142
|
+
"attributes": {
|
|
143
|
+
"sourceName": "HR Source",
|
|
144
|
+
"attributeName": "employeeType"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"name": "Case-Normalized Status Lookup",
|
|
151
|
+
"type": "lookup",
|
|
152
|
+
"attributes": {
|
|
153
|
+
"table": {
|
|
154
|
+
"active": "Active",
|
|
155
|
+
"inactive": "Inactive",
|
|
156
|
+
"pending": "Pending Activation",
|
|
157
|
+
"default": "Unknown Status"
|
|
158
|
+
},
|
|
159
|
+
"input": {
|
|
160
|
+
"type": "lower",
|
|
161
|
+
"attributes": {
|
|
162
|
+
"input": {
|
|
163
|
+
"type": "accountAttribute",
|
|
164
|
+
"attributes": {
|
|
165
|
+
"sourceName": "HR Source",
|
|
166
|
+
"attributeName": "status"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
98
172
|
}
|
|
99
173
|
]
|
|
100
174
|
}
|
package/dist/transforms/lint.js
CHANGED
|
@@ -927,22 +927,58 @@ function lintIso3166(attrs) {
|
|
|
927
927
|
return msgs;
|
|
928
928
|
}
|
|
929
929
|
// ---------------------------------------------------------------------------
|
|
930
|
-
// 18. lookup — table validation
|
|
930
|
+
// 18. lookup — table validation, default key, case-sensitivity, input
|
|
931
|
+
// Docs: https://developer.sailpoint.com/docs/extensibility/transforms/operations/lookup
|
|
931
932
|
// ---------------------------------------------------------------------------
|
|
932
933
|
function lintLookup(attrs) {
|
|
933
934
|
const msgs = [];
|
|
934
935
|
if (attrs?.table !== undefined) {
|
|
935
936
|
if (!isPlainObject(attrs.table)) {
|
|
936
|
-
push(msgs, "error", "table must be an object map of
|
|
937
|
+
push(msgs, "error", "table must be an object map of string keys to string output values (e.g., {\"US\": \"United States\", \"default\": \"Unknown\"}). " +
|
|
938
|
+
"Nested transforms and conditional logic are not supported as table values.", "attributes.table");
|
|
937
939
|
}
|
|
938
940
|
else {
|
|
941
|
+
const tableKeys = Object.keys(attrs.table);
|
|
942
|
+
// 1. default key is mandatory per docs — unmatched input causes a runtime error without it
|
|
939
943
|
if (!Object.prototype.hasOwnProperty.call(attrs.table, "default")) {
|
|
940
|
-
push(msgs, "
|
|
944
|
+
push(msgs, "error", "lookup table must include a 'default' key. Without it, any input that doesn't match a table key " +
|
|
945
|
+
"causes a runtime error. Add: \"default\": \"<fallback value>\".", "attributes.table");
|
|
941
946
|
}
|
|
947
|
+
// 2. All values must be strings — nested transforms and dynamic values are not supported
|
|
942
948
|
const badVals = Object.entries(attrs.table).filter(([, v]) => typeof v !== "string");
|
|
943
949
|
if (badVals.length) {
|
|
944
|
-
push(msgs, "error", `All lookup table values must be strings. Non-string entries: ${badVals.map(([k]) => k).join(", ")}
|
|
950
|
+
push(msgs, "error", `All lookup table values must be static strings. Non-string entries: ${badVals.map(([k]) => `'${k}'`).join(", ")}. ` +
|
|
951
|
+
"Nested transforms and conditional logic inside table values are not supported.", "attributes.table");
|
|
945
952
|
}
|
|
953
|
+
// 3. Empty table (no keys at all — can't happen if default is required, but guard anyway)
|
|
954
|
+
if (tableKeys.length === 0) {
|
|
955
|
+
push(msgs, "error", "lookup table is empty. Add at least a 'default' key and one or more mapping entries.", "attributes.table");
|
|
956
|
+
// 4. Table has only a default key — no lookup entries, always returns default
|
|
957
|
+
}
|
|
958
|
+
else if (tableKeys.length === 1 && tableKeys[0] === "default") {
|
|
959
|
+
push(msgs, "warn", "lookup table contains only a 'default' key with no other mapping entries. " +
|
|
960
|
+
"This will always return the default value regardless of input. " +
|
|
961
|
+
"If you want a fixed output, use a static transform instead.", "attributes.table");
|
|
962
|
+
}
|
|
963
|
+
// 5. Empty-string key — unusual, only matches when input is an empty string
|
|
964
|
+
if (tableKeys.includes("")) {
|
|
965
|
+
push(msgs, "warn", "lookup table contains an empty-string key (\"\"). This matches only when the input value is an empty string. " +
|
|
966
|
+
"If unintentional, remove it.", "attributes.table");
|
|
967
|
+
}
|
|
968
|
+
// 6. Case-sensitivity info — only when there are real mapping entries
|
|
969
|
+
if (tableKeys.filter(k => k !== "default").length > 0) {
|
|
970
|
+
push(msgs, "info", "Lookup table comparisons are case-sensitive — table keys must match the input value exactly. " +
|
|
971
|
+
"'US' and 'us' are treated as different keys. " +
|
|
972
|
+
"If case may vary in the input, normalize it first with a lower or upper transform.", "attributes.table");
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
// 7. input: validate type if provided
|
|
977
|
+
if (attrs?.input !== undefined) {
|
|
978
|
+
const inp = attrs.input;
|
|
979
|
+
if (!(typeof inp === "string" || (isPlainObject(inp) && typeof inp.type === "string"))) {
|
|
980
|
+
push(msgs, "warn", "input must be a nested transform object {type, attributes} that provides the value to look up, or a static string. " +
|
|
981
|
+
"If omitted, the transform uses the source+attribute combination configured in the identity profile UI.", "attributes.input");
|
|
946
982
|
}
|
|
947
983
|
}
|
|
948
984
|
return msgs;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isc-transforms-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server for SailPoint Identity Security Cloud (ISC) Transform authoring — scaffold, strict lint, catalog, and safe upsert to live tenants.",
|
|
6
6
|
"author": {
|