@tenonhq/dovetail-servicenow 0.0.28 → 0.0.29
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/choices.d.ts +1 -0
- package/dist/choices.js +34 -16
- package/dist/cli.js +126 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +4 -1
- package/dist/mcp/registry.d.ts +1 -1
- package/dist/mcp/registry.js +53 -11
- package/dist/mcp/schemas.d.ts +84 -0
- package/dist/mcp/schemas.js +94 -47
- package/dist/table/index.d.ts +7 -5
- package/dist/table/index.js +6 -1
- package/dist/table/setColumn.d.ts +153 -0
- package/dist/table/setColumn.js +639 -0
- package/package.json +1 -1
package/dist/choices.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ServiceNowClient } from "./client";
|
|
11
11
|
import type { AddChoicesParams, AddChoicesResult } from "./types";
|
|
12
|
+
export declare function encodeQueryValue(v: string): string;
|
|
12
13
|
/**
|
|
13
14
|
* Upsert choices for a field and (optionally) toggle sys_dictionary.choice.
|
|
14
15
|
* Idempotent: re-running with the same inputs returns `action: "unchanged"`
|
package/dist/choices.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* so choices stay in the same application as the field.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.encodeQueryValue = encodeQueryValue;
|
|
12
13
|
exports.addChoicesToField = addChoicesToField;
|
|
13
14
|
function encodeQueryValue(v) {
|
|
14
15
|
// ServiceNow encoded-query values: commas/carets/equals are special. We
|
|
@@ -39,7 +40,10 @@ async function resolveScopeName(client, scopeSysId) {
|
|
|
39
40
|
async function fetchDictionary(client, table, column) {
|
|
40
41
|
var rows = await client.table.query("sys_dictionary", "name=" + encodeQueryValue(table) + "^element=" + encodeQueryValue(column), 1);
|
|
41
42
|
if (rows.length === 0) {
|
|
42
|
-
throw new Error("sys_dictionary record not found for " +
|
|
43
|
+
throw new Error("sys_dictionary record not found for " +
|
|
44
|
+
table +
|
|
45
|
+
"." +
|
|
46
|
+
column +
|
|
43
47
|
" — verify the field exists and your user has read access.");
|
|
44
48
|
}
|
|
45
49
|
var row = rows[0];
|
|
@@ -53,7 +57,7 @@ async function fetchDictionary(client, table, column) {
|
|
|
53
57
|
name: row.name,
|
|
54
58
|
element: row.element,
|
|
55
59
|
choice: String(row.choice || "0"),
|
|
56
|
-
sys_scope: scope || ""
|
|
60
|
+
sys_scope: scope || "",
|
|
57
61
|
};
|
|
58
62
|
}
|
|
59
63
|
async function fetchUpdateSet(client, sysId) {
|
|
@@ -63,14 +67,16 @@ async function fetchUpdateSet(client, sysId) {
|
|
|
63
67
|
}
|
|
64
68
|
var row = rows[0];
|
|
65
69
|
if (row.state && row.state !== "in progress" && row.state !== "in_progress") {
|
|
66
|
-
throw new Error("Update set " +
|
|
70
|
+
throw new Error("Update set " +
|
|
71
|
+
row.name +
|
|
72
|
+
" is in state '" +
|
|
73
|
+
row.state +
|
|
67
74
|
"' — only 'in progress' update sets can capture new changes.");
|
|
68
75
|
}
|
|
69
76
|
return row;
|
|
70
77
|
}
|
|
71
78
|
async function fetchExistingChoices(client, table, column) {
|
|
72
|
-
return client.table.query("sys_choice", "name=" + encodeQueryValue(table) +
|
|
73
|
-
"^element=" + encodeQueryValue(column), 1000);
|
|
79
|
+
return client.table.query("sys_choice", "name=" + encodeQueryValue(table) + "^element=" + encodeQueryValue(column), 1000);
|
|
74
80
|
}
|
|
75
81
|
function buildChoiceFields(table, column, choice, scope) {
|
|
76
82
|
var fields = {
|
|
@@ -79,7 +85,7 @@ function buildChoiceFields(table, column, choice, scope) {
|
|
|
79
85
|
value: choice.value,
|
|
80
86
|
label: choice.label,
|
|
81
87
|
language: choice.language || "en",
|
|
82
|
-
inactive: "false"
|
|
88
|
+
inactive: "false",
|
|
83
89
|
};
|
|
84
90
|
if (choice.sequence != null) {
|
|
85
91
|
fields.sequence = String(choice.sequence);
|
|
@@ -114,7 +120,9 @@ async function addChoicesToField(client, params) {
|
|
|
114
120
|
var scopeName = await resolveScopeName(client, dict.sys_scope);
|
|
115
121
|
var targetChoiceType = params.choiceType === null
|
|
116
122
|
? Number(dict.choice)
|
|
117
|
-
:
|
|
123
|
+
: params.choiceType != null
|
|
124
|
+
? params.choiceType
|
|
125
|
+
: 3;
|
|
118
126
|
var choiceWas = Number(dict.choice);
|
|
119
127
|
var choiceNow = choiceWas;
|
|
120
128
|
if (params.choiceType !== null && Number(dict.choice) !== targetChoiceType) {
|
|
@@ -122,7 +130,7 @@ async function addChoicesToField(client, params) {
|
|
|
122
130
|
update_set_sys_id: params.updateSetSysId,
|
|
123
131
|
table: "sys_dictionary",
|
|
124
132
|
record_sys_id: dict.sys_id,
|
|
125
|
-
fields: { choice: String(targetChoiceType) }
|
|
133
|
+
fields: { choice: String(targetChoiceType) },
|
|
126
134
|
});
|
|
127
135
|
choiceNow = targetChoiceType;
|
|
128
136
|
}
|
|
@@ -138,14 +146,19 @@ async function addChoicesToField(client, params) {
|
|
|
138
146
|
var key = (choice.language || "en") + "::" + choice.value;
|
|
139
147
|
var match = existingByValue[key];
|
|
140
148
|
if (match && isUnchanged(match, choice)) {
|
|
141
|
-
results.push({
|
|
149
|
+
results.push({
|
|
150
|
+
value: choice.value,
|
|
151
|
+
label: choice.label,
|
|
152
|
+
sysId: match.sys_id,
|
|
153
|
+
action: "unchanged",
|
|
154
|
+
});
|
|
142
155
|
continue;
|
|
143
156
|
}
|
|
144
157
|
if (match) {
|
|
145
158
|
var updFields = {
|
|
146
159
|
label: choice.label,
|
|
147
160
|
language: choice.language || "en",
|
|
148
|
-
inactive: "false"
|
|
161
|
+
inactive: "false",
|
|
149
162
|
};
|
|
150
163
|
if (choice.sequence != null) {
|
|
151
164
|
updFields.sequence = String(choice.sequence);
|
|
@@ -154,22 +167,27 @@ async function addChoicesToField(client, params) {
|
|
|
154
167
|
update_set_sys_id: params.updateSetSysId,
|
|
155
168
|
table: "sys_choice",
|
|
156
169
|
record_sys_id: match.sys_id,
|
|
157
|
-
fields: updFields
|
|
170
|
+
fields: updFields,
|
|
171
|
+
});
|
|
172
|
+
results.push({
|
|
173
|
+
value: choice.value,
|
|
174
|
+
label: choice.label,
|
|
175
|
+
sysId: match.sys_id,
|
|
176
|
+
action: "updated",
|
|
158
177
|
});
|
|
159
|
-
results.push({ value: choice.value, label: choice.label, sysId: match.sys_id, action: "updated" });
|
|
160
178
|
continue;
|
|
161
179
|
}
|
|
162
180
|
var created = await client.claude.createRecord({
|
|
163
181
|
table: "sys_choice",
|
|
164
182
|
fields: buildChoiceFields(params.table, params.column, choice, dict.sys_scope),
|
|
165
183
|
scope: scopeName,
|
|
166
|
-
update_set_sys_id: params.updateSetSysId
|
|
184
|
+
update_set_sys_id: params.updateSetSysId,
|
|
167
185
|
});
|
|
168
186
|
results.push({
|
|
169
187
|
value: choice.value,
|
|
170
188
|
label: choice.label,
|
|
171
189
|
sysId: created.sys_id,
|
|
172
|
-
action: "created"
|
|
190
|
+
action: "created",
|
|
173
191
|
});
|
|
174
192
|
}
|
|
175
193
|
return {
|
|
@@ -177,9 +195,9 @@ async function addChoicesToField(client, params) {
|
|
|
177
195
|
sysId: dict.sys_id,
|
|
178
196
|
scope: dict.sys_scope,
|
|
179
197
|
choiceWas: choiceWas,
|
|
180
|
-
choiceNow: choiceNow
|
|
198
|
+
choiceNow: choiceNow,
|
|
181
199
|
},
|
|
182
200
|
updateSet: { sysId: updateSet.sys_id, name: updateSet.name },
|
|
183
|
-
choices: results
|
|
201
|
+
choices: results,
|
|
184
202
|
};
|
|
185
203
|
}
|
package/dist/cli.js
CHANGED
|
@@ -87,24 +87,30 @@ const flowDesigner_formatter_2 = require("./flowDesigner-formatter");
|
|
|
87
87
|
function parseArgs(argv) {
|
|
88
88
|
var command = argv[0] || "";
|
|
89
89
|
var flags = {};
|
|
90
|
+
var bare = {};
|
|
90
91
|
for (var i = 1; i < argv.length; i += 1) {
|
|
91
92
|
var arg = argv[i];
|
|
92
93
|
if (arg.indexOf("--") !== 0)
|
|
93
94
|
continue;
|
|
94
95
|
var key = arg.slice(2);
|
|
95
96
|
var value = "true";
|
|
97
|
+
var isBare = true;
|
|
96
98
|
var eq = key.indexOf("=");
|
|
97
99
|
if (eq !== -1) {
|
|
98
100
|
value = key.slice(eq + 1);
|
|
99
101
|
key = key.slice(0, eq);
|
|
102
|
+
isBare = false;
|
|
100
103
|
}
|
|
101
104
|
else if (i + 1 < argv.length && argv[i + 1].indexOf("--") !== 0) {
|
|
102
105
|
value = argv[i + 1];
|
|
103
106
|
i += 1;
|
|
107
|
+
isBare = false;
|
|
104
108
|
}
|
|
105
109
|
flags[key] = value;
|
|
110
|
+
if (isBare)
|
|
111
|
+
bare[key] = true;
|
|
106
112
|
}
|
|
107
|
-
return { command: command, flags: flags };
|
|
113
|
+
return { command: command, flags: flags, bare: bare };
|
|
108
114
|
}
|
|
109
115
|
function parseChoicesInline(input) {
|
|
110
116
|
return input.split(",").map(function (pair) {
|
|
@@ -876,6 +882,17 @@ function printHelp() {
|
|
|
876
882
|
" [--name <element>] [--max-length <n>] [--reference <table>]\n" +
|
|
877
883
|
" [--mandatory] [--default <v>] [--scope <s>] [--dry-run] [--json])\n" +
|
|
878
884
|
" --update-set is REQUIRED on the live path (not for --dry-run).\n" +
|
|
885
|
+
" set-column Update an EXISTING column's SCHEMA (label/mandatory/default/read-only/max-length),\n" +
|
|
886
|
+
" into an update set, then verify against the instance\n" +
|
|
887
|
+
" (--table <t> --column <c> --update-set <sys_id>\n" +
|
|
888
|
+
" [--label <l>] [--mandatory true|false] [--default <v>]\n" +
|
|
889
|
+
" [--read-only true|false] [--max-length <n>]\n" +
|
|
890
|
+
" [--dry-run] [--json])\n" +
|
|
891
|
+
" A max-length SHRINK is REFUSED while rows hold longer values —\n" +
|
|
892
|
+
" ServiceNow silently ignores such a shrink (200 OK, no change).\n" +
|
|
893
|
+
" Shorten or clear those values first, then re-run.\n" +
|
|
894
|
+
" --element / --internal-type are REFUSED with an explanation:\n" +
|
|
895
|
+
" ServiceNow silently ignores both on an existing column.\n" +
|
|
879
896
|
" invoke-rest Invoke an arbitrary authenticated REST operation (Scripted REST incl.)\n" +
|
|
880
897
|
" DRY-RUN BY DEFAULT — nothing is sent without --confirm\n" +
|
|
881
898
|
" (--method <GET|POST|PUT|DELETE> --path /api/<scope>/<service>/<resource>\n" +
|
|
@@ -1087,6 +1104,111 @@ async function runAddColumn(flags) {
|
|
|
1087
1104
|
return 2;
|
|
1088
1105
|
return 0;
|
|
1089
1106
|
}
|
|
1107
|
+
/** Parse a CLI boolean flag. Bare `--mandatory` means true; `--mandatory false` means
|
|
1108
|
+
* false. Anything else is rejected rather than quietly coerced to `true`. */
|
|
1109
|
+
function parseBoolFlag(name, raw) {
|
|
1110
|
+
if (raw === "true")
|
|
1111
|
+
return true;
|
|
1112
|
+
if (raw === "false")
|
|
1113
|
+
return false;
|
|
1114
|
+
throw new Error("set-column: --" + name + " must be true or false (got '" + raw + "').");
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* dove-sn set-column:
|
|
1118
|
+
* --table x_cadso_journey --column description --update-set <sys_id>
|
|
1119
|
+
* [--label "Description"] [--mandatory true|false] [--default <v>]
|
|
1120
|
+
* [--read-only true|false] [--max-length 4000] [--dry-run] [--json]
|
|
1121
|
+
*
|
|
1122
|
+
* Updates an EXISTING column's schema. `internal_type` and a rename are refused —
|
|
1123
|
+
* ServiceNow silently ignores both on an existing column. To CREATE one, use add-column;
|
|
1124
|
+
* to set a RECORD's value, use set-field.
|
|
1125
|
+
*/
|
|
1126
|
+
async function runSetColumn(flags, bare) {
|
|
1127
|
+
// A string flag whose value was forgotten arrives as the literal "true" — `--label`
|
|
1128
|
+
// with nothing after it would rename the column to "true". Booleans legitimately do
|
|
1129
|
+
// that, strings never do, so refuse rather than silently write nonsense.
|
|
1130
|
+
var stringFlags = ["label", "default", "table", "column", "update-set"];
|
|
1131
|
+
for (var f = 0; f < stringFlags.length; f += 1) {
|
|
1132
|
+
if (bare[stringFlags[f]]) {
|
|
1133
|
+
process.stderr.write("set-column: --" +
|
|
1134
|
+
stringFlags[f] +
|
|
1135
|
+
" needs a value (it was given none).\n");
|
|
1136
|
+
return 1;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
var table = flags.table;
|
|
1140
|
+
var column = flags.column;
|
|
1141
|
+
if (!table || !column) {
|
|
1142
|
+
process.stderr.write("set-column: --table and --column are required " +
|
|
1143
|
+
"(--update-set is required too, unless --dry-run)\n");
|
|
1144
|
+
return 1;
|
|
1145
|
+
}
|
|
1146
|
+
var attributes = {};
|
|
1147
|
+
// Accepted so that setColumn can REFUSE them by name with the reason. Dropping them
|
|
1148
|
+
// silently would leave someone who asked for a rename believing it happened.
|
|
1149
|
+
if (flags.element !== undefined)
|
|
1150
|
+
attributes.element = flags.element;
|
|
1151
|
+
if (flags["internal-type"] !== undefined) {
|
|
1152
|
+
attributes.internalType = flags["internal-type"];
|
|
1153
|
+
}
|
|
1154
|
+
if (flags.label !== undefined)
|
|
1155
|
+
attributes.label = flags.label;
|
|
1156
|
+
if (flags.default !== undefined)
|
|
1157
|
+
attributes.default = flags.default;
|
|
1158
|
+
if (flags.mandatory !== undefined) {
|
|
1159
|
+
attributes.mandatory = parseBoolFlag("mandatory", flags.mandatory);
|
|
1160
|
+
}
|
|
1161
|
+
if (flags["read-only"] !== undefined) {
|
|
1162
|
+
attributes.readOnly = parseBoolFlag("read-only", flags["read-only"]);
|
|
1163
|
+
}
|
|
1164
|
+
if (flags["max-length"] !== undefined) {
|
|
1165
|
+
var len = Number(flags["max-length"]);
|
|
1166
|
+
// sys_dictionary.max_length is an integer; the MCP schema enforces int() too.
|
|
1167
|
+
if (!Number.isInteger(len) || len < 1) {
|
|
1168
|
+
process.stderr.write("set-column: --max-length must be a positive integer\n");
|
|
1169
|
+
return 1;
|
|
1170
|
+
}
|
|
1171
|
+
attributes.maxLength = len;
|
|
1172
|
+
}
|
|
1173
|
+
var params = {
|
|
1174
|
+
client: (0, client_1.createClient)({}),
|
|
1175
|
+
table: table,
|
|
1176
|
+
column: column,
|
|
1177
|
+
attributes: attributes,
|
|
1178
|
+
};
|
|
1179
|
+
// Accept the same alias pair as the other verbs (create-view, set-list-layout, …).
|
|
1180
|
+
var setColumnUs = flags["update-set"] || flags.updateSetSysId;
|
|
1181
|
+
if (setColumnUs)
|
|
1182
|
+
params.updateSetSysId = setColumnUs;
|
|
1183
|
+
if (flags["dry-run"] === "true")
|
|
1184
|
+
params.dryRun = true;
|
|
1185
|
+
var result = await (0, table_1.setColumn)(params);
|
|
1186
|
+
if (flags.json === "true") {
|
|
1187
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
1188
|
+
}
|
|
1189
|
+
else {
|
|
1190
|
+
process.stdout.write("[" +
|
|
1191
|
+
result.status +
|
|
1192
|
+
"] " +
|
|
1193
|
+
result.table +
|
|
1194
|
+
"." +
|
|
1195
|
+
result.column +
|
|
1196
|
+
(result.verified && result.status === "applied" ? " — verified" : "") +
|
|
1197
|
+
(result.status === "applied" && !result.capturedInUpdateSet
|
|
1198
|
+
? " — NOT CAPTURED"
|
|
1199
|
+
: "") +
|
|
1200
|
+
"\n" +
|
|
1201
|
+
result.note +
|
|
1202
|
+
"\n");
|
|
1203
|
+
}
|
|
1204
|
+
// 2 = the write landed but the instance does not reflect it (or it was not captured),
|
|
1205
|
+
// which must not read as success to a script.
|
|
1206
|
+
if (result.status === "failed")
|
|
1207
|
+
return 2;
|
|
1208
|
+
if (result.status === "applied" && !result.capturedInUpdateSet)
|
|
1209
|
+
return 2;
|
|
1210
|
+
return 0;
|
|
1211
|
+
}
|
|
1090
1212
|
/** Parse inline `--fields "k=v, k2=v2"` into a field map. */
|
|
1091
1213
|
function parseFieldsInline(input) {
|
|
1092
1214
|
var out = {};
|
|
@@ -1388,6 +1510,9 @@ async function main() {
|
|
|
1388
1510
|
if (parsed.command === "add-column") {
|
|
1389
1511
|
return await runAddColumn(parsed.flags);
|
|
1390
1512
|
}
|
|
1513
|
+
if (parsed.command === "set-column") {
|
|
1514
|
+
return await runSetColumn(parsed.flags, parsed.bare);
|
|
1515
|
+
}
|
|
1391
1516
|
if (parsed.command === "set-field") {
|
|
1392
1517
|
return await runSetField(parsed.flags);
|
|
1393
1518
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* REST API so every change lands in the target update set and scope.
|
|
6
6
|
*/
|
|
7
7
|
export { createClient } from "./client";
|
|
8
|
-
export { createClientFromEnvFile, resolveConfigFromEnvFile } from "./createClientFromEnvFile";
|
|
9
|
-
export type { ServiceNowClient, TableQueryOptions, TableSchema, TableSchemaField, AttachmentMeta, NowInvokeMethod, NowInvokeParams, NowInvokeResponse } from "./client";
|
|
8
|
+
export { createClientFromEnvFile, resolveConfigFromEnvFile, } from "./createClientFromEnvFile";
|
|
9
|
+
export type { ServiceNowClient, TableQueryOptions, TableSchema, TableSchemaField, AttachmentMeta, NowInvokeMethod, NowInvokeParams, NowInvokeResponse, } from "./client";
|
|
10
10
|
export { addChoicesToField } from "./choices";
|
|
11
|
-
export { hostAssets, classifyChunks, formatHostAssetsResult } from "./hostAssets";
|
|
11
|
+
export { hostAssets, classifyChunks, formatHostAssetsResult, } from "./hostAssets";
|
|
12
12
|
export { formatAddChoicesResult } from "./formatter";
|
|
13
13
|
export { createView } from "./layout/views";
|
|
14
14
|
export { setListLayout } from "./layout/listLayout";
|
|
@@ -16,14 +16,14 @@ export { setFormLayout } from "./layout/formLayout";
|
|
|
16
16
|
export { setRelatedLists } from "./layout/relatedLists";
|
|
17
17
|
export { formatLayoutResult, formatCreateViewResult } from "./layout/formatter";
|
|
18
18
|
export { sincPlugin } from "./plugin";
|
|
19
|
-
export { listTemplates, verifyArtifact, cloneSubflow, cloneActionType, triggerPublication, publishActionType, editActionType, applyStepOps, verifySteps, summarizeSteps, formatStepPill, readFlow, readActionType, publishFlow, copyFlow, createFlow, buildPublishModel, editFlow, testFlow, DEFAULT_RUN_FLOW_PATH, generateSysId, topoSort, executeWritePlan, WriteOrderError } from "./flowDesigner";
|
|
20
|
-
export type { TemplateRef, ListTemplatesParams, FlowKind, VerifyExpect, VerifyFound, VerifyFailure, VerifyReport, VerifyArtifactParams, CloneSubflowParams, CloneSubflowResult, CloneActionTypeParams, CloneActionTypeResult, TriggerPublicationParams, TriggerPublicationResult, PublishActionTypeParams, PublishActionTypeResult, EditActionTypeParams, EditActionTypeResult, EditActionTypeOps, StepOps, StepRecord, StepSummary, StepIoSummary, PatchStepScriptOp, AddStepOutputOp, AddStepInputOp, ApplyStepOpsResult, VerifyStepsResult, ReadFlowParams, ReadFlowResult, FlowStep, FlowVariable, ReadActionTypeParams, ReadActionTypeResult, ActionIo, PublishFlowParams, PublishFlowResult, CopyFlowParams, CopyFlowResult, CreateFlowParams, CreateFlowResult, EditFlowParams, EditFlowResult, EditFlowOps, StepInputPatch, TestFlowParams, TestFlowResult, WriteOp, WriteOpResult } from "./flowDesigner";
|
|
21
|
-
export type { ServiceNowClientConfig, ChoiceValue, ChoiceType, AddChoicesParams, AddChoicesResult, ChoiceActionResult, DictionaryRecord, UpdateSetRecord, LayoutAction, LayoutRecordResult, LayoutResult, CreateViewParams, CreateViewResult, FormSectionSpec, SetFormLayoutParams, SetListLayoutParams, SetRelatedListsParams, ChunkRole, ChunkInfo, ChunkResult, PrunedResult, HostAssetsParams, HostAssetsResult } from "./types";
|
|
22
|
-
export { createTable, projectTableGraph, buildColumnXml, normalizeColumns, resolveType, applyTableSaveOverlay, defaultAccessFlags, TYPE_MAP, DEFAULT_SUPER_CLASS, DEFAULT_SAVE_ACTION, addColumn, deriveElement } from "./table";
|
|
23
|
-
export type { CreateTableParams, CreateTableResult, AddColumnParams, AddColumnResult, TableGraph, NormalizedColumn, ColumnSpec, AccessFlags, OverlaySpec } from "./table";
|
|
19
|
+
export { listTemplates, verifyArtifact, cloneSubflow, cloneActionType, triggerPublication, publishActionType, editActionType, applyStepOps, verifySteps, summarizeSteps, formatStepPill, readFlow, readActionType, publishFlow, copyFlow, createFlow, buildPublishModel, editFlow, testFlow, DEFAULT_RUN_FLOW_PATH, generateSysId, topoSort, executeWritePlan, WriteOrderError, } from "./flowDesigner";
|
|
20
|
+
export type { TemplateRef, ListTemplatesParams, FlowKind, VerifyExpect, VerifyFound, VerifyFailure, VerifyReport, VerifyArtifactParams, CloneSubflowParams, CloneSubflowResult, CloneActionTypeParams, CloneActionTypeResult, TriggerPublicationParams, TriggerPublicationResult, PublishActionTypeParams, PublishActionTypeResult, EditActionTypeParams, EditActionTypeResult, EditActionTypeOps, StepOps, StepRecord, StepSummary, StepIoSummary, PatchStepScriptOp, AddStepOutputOp, AddStepInputOp, ApplyStepOpsResult, VerifyStepsResult, ReadFlowParams, ReadFlowResult, FlowStep, FlowVariable, ReadActionTypeParams, ReadActionTypeResult, ActionIo, PublishFlowParams, PublishFlowResult, CopyFlowParams, CopyFlowResult, CreateFlowParams, CreateFlowResult, EditFlowParams, EditFlowResult, EditFlowOps, StepInputPatch, TestFlowParams, TestFlowResult, WriteOp, WriteOpResult, } from "./flowDesigner";
|
|
21
|
+
export type { ServiceNowClientConfig, ChoiceValue, ChoiceType, AddChoicesParams, AddChoicesResult, ChoiceActionResult, DictionaryRecord, UpdateSetRecord, LayoutAction, LayoutRecordResult, LayoutResult, CreateViewParams, CreateViewResult, FormSectionSpec, SetFormLayoutParams, SetListLayoutParams, SetRelatedListsParams, ChunkRole, ChunkInfo, ChunkResult, PrunedResult, HostAssetsParams, HostAssetsResult, } from "./types";
|
|
22
|
+
export { createTable, projectTableGraph, buildColumnXml, normalizeColumns, resolveType, applyTableSaveOverlay, defaultAccessFlags, TYPE_MAP, DEFAULT_SUPER_CLASS, DEFAULT_SAVE_ACTION, addColumn, deriveElement, setColumn, resolveAttributes, toStoredValue, } from "./table";
|
|
23
|
+
export type { CreateTableParams, CreateTableResult, AddColumnParams, AddColumnResult, SetColumnParams, SetColumnResult, ColumnAttributes, AttributeChange, TableGraph, NormalizedColumn, ColumnSpec, AccessFlags, OverlaySpec, } from "./table";
|
|
24
24
|
export { setField } from "./setField";
|
|
25
25
|
export { createRecord } from "./createRecord";
|
|
26
|
-
export type { RecordWriteResult, SetFieldParams, SetFieldResult } from "./setField";
|
|
26
|
+
export type { RecordWriteResult, SetFieldParams, SetFieldResult, } from "./setField";
|
|
27
27
|
export type { CreateRecordParams, CreateRecordResult } from "./createRecord";
|
|
28
28
|
export { invokeRest, INVOKE_REST_METHODS } from "./invokeRest";
|
|
29
29
|
export type { InvokeRestParams, InvokeRestResult } from "./invokeRest";
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.addColumn = exports.DEFAULT_SAVE_ACTION = exports.DEFAULT_SUPER_CLASS = exports.TYPE_MAP = exports.defaultAccessFlags = exports.applyTableSaveOverlay = exports.resolveType = exports.normalizeColumns = exports.buildColumnXml = exports.projectTableGraph = exports.createTable = exports.WriteOrderError = exports.executeWritePlan = exports.topoSort = exports.generateSysId = exports.DEFAULT_RUN_FLOW_PATH = exports.testFlow = exports.editFlow = exports.buildPublishModel = exports.createFlow = exports.copyFlow = exports.publishFlow = exports.readActionType = exports.readFlow = exports.formatStepPill = exports.summarizeSteps = exports.verifySteps = exports.applyStepOps = exports.editActionType = exports.publishActionType = exports.triggerPublication = exports.cloneActionType = exports.cloneSubflow = exports.verifyArtifact = exports.listTemplates = exports.sincPlugin = exports.formatCreateViewResult = exports.formatLayoutResult = exports.setRelatedLists = exports.setFormLayout = exports.setListLayout = exports.createView = exports.formatAddChoicesResult = exports.formatHostAssetsResult = exports.classifyChunks = exports.hostAssets = exports.addChoicesToField = exports.resolveConfigFromEnvFile = exports.createClientFromEnvFile = exports.createClient = void 0;
|
|
10
|
-
exports.INVOKE_REST_METHODS = exports.invokeRest = exports.createRecord = exports.setField = exports.deriveElement = void 0;
|
|
10
|
+
exports.INVOKE_REST_METHODS = exports.invokeRest = exports.createRecord = exports.setField = exports.toStoredValue = exports.resolveAttributes = exports.setColumn = exports.deriveElement = void 0;
|
|
11
11
|
var client_1 = require("./client");
|
|
12
12
|
Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return client_1.createClient; } });
|
|
13
13
|
var createClientFromEnvFile_1 = require("./createClientFromEnvFile");
|
|
@@ -72,6 +72,9 @@ Object.defineProperty(exports, "DEFAULT_SUPER_CLASS", { enumerable: true, get: f
|
|
|
72
72
|
Object.defineProperty(exports, "DEFAULT_SAVE_ACTION", { enumerable: true, get: function () { return table_1.DEFAULT_SAVE_ACTION; } });
|
|
73
73
|
Object.defineProperty(exports, "addColumn", { enumerable: true, get: function () { return table_1.addColumn; } });
|
|
74
74
|
Object.defineProperty(exports, "deriveElement", { enumerable: true, get: function () { return table_1.deriveElement; } });
|
|
75
|
+
Object.defineProperty(exports, "setColumn", { enumerable: true, get: function () { return table_1.setColumn; } });
|
|
76
|
+
Object.defineProperty(exports, "resolveAttributes", { enumerable: true, get: function () { return table_1.resolveAttributes; } });
|
|
77
|
+
Object.defineProperty(exports, "toStoredValue", { enumerable: true, get: function () { return table_1.toStoredValue; } });
|
|
75
78
|
var setField_1 = require("./setField");
|
|
76
79
|
Object.defineProperty(exports, "setField", { enumerable: true, get: function () { return setField_1.setField; } });
|
|
77
80
|
var createRecord_1 = require("./createRecord");
|
package/dist/mcp/registry.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
import type { ToolAnnotations } from "@tenonhq/dovetail-mcp-kit";
|
|
12
12
|
import type { ServiceNowClient } from "../client";
|
|
13
|
-
export declare var TOOL_NAMES: readonly ["create_view", "set_list_layout", "set_form_layout", "set_related_lists", "add_choices_to_field", "flow_view", "action_view", "action_edit", "flow_publish", "flow_copy", "flow_create", "flow_test", "flow_edit", "create_table", "add_column", "set_field", "create_record", "host_assets", "invoke_rest"];
|
|
13
|
+
export declare var TOOL_NAMES: readonly ["create_view", "set_list_layout", "set_form_layout", "set_related_lists", "add_choices_to_field", "flow_view", "action_view", "action_edit", "flow_publish", "flow_copy", "flow_create", "flow_test", "flow_edit", "create_table", "add_column", "set_column", "set_field", "create_record", "host_assets", "invoke_rest"];
|
|
14
14
|
export type ToolName = (typeof TOOL_NAMES)[number];
|
|
15
15
|
export interface RegistryDeps {
|
|
16
16
|
/** Optional client injection for tests; defaults to createClient({}). */
|
package/dist/mcp/registry.js
CHANGED
|
@@ -48,6 +48,7 @@ exports.TOOL_NAMES = [
|
|
|
48
48
|
"flow_edit",
|
|
49
49
|
"create_table",
|
|
50
50
|
"add_column",
|
|
51
|
+
"set_column",
|
|
51
52
|
"set_field",
|
|
52
53
|
"create_record",
|
|
53
54
|
"host_assets",
|
|
@@ -150,15 +151,15 @@ function buildDescriptors(deps = {}) {
|
|
|
150
151
|
{
|
|
151
152
|
name: "action_edit",
|
|
152
153
|
annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
|
|
153
|
-
description: "Structurally edit a published Custom Action Type and republish it as one snapshot. "
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
description: "Structurally edit a published Custom Action Type and republish it as one snapshot. " +
|
|
155
|
+
"Ops: patchStepScripts (per-step script edits, step addressed by cid or label), " +
|
|
156
|
+
"addStepOutputs (step-level extended_outputs), addStepInputs (step-level extended_inputs " +
|
|
157
|
+
"wired to another step's output via pillFrom {step, output} — the pill format and the " +
|
|
158
|
+
"entry shape are handled for you). Also supports the action-level patchScript / setScript / " +
|
|
159
|
+
"mergeOutputs. DRY-RUN BY DEFAULT: without apply:true it returns the per-step before/after " +
|
|
160
|
+
"diff and writes nothing. With apply:true it POSTs /snapshot, captures into updateSetSysId " +
|
|
161
|
+
"when given, then reads the steps back and verifies the edit actually landed. " +
|
|
162
|
+
"sysId is the sys_hub_action_type_definition sys_id; scopeSysId is the app scope.",
|
|
162
163
|
shape: schemas_1.editActionSchema.shape,
|
|
163
164
|
handler: async function (args) {
|
|
164
165
|
var p = schemas_1.editActionSchema.parse(args);
|
|
@@ -168,9 +169,9 @@ function buildDescriptors(deps = {}) {
|
|
|
168
169
|
scopeSysId: p.scopeSysId,
|
|
169
170
|
ops: p.ops,
|
|
170
171
|
apply: p.apply === true,
|
|
171
|
-
updateSetSysId: p.updateSetSysId
|
|
172
|
+
updateSetSysId: p.updateSetSysId,
|
|
172
173
|
});
|
|
173
|
-
}
|
|
174
|
+
},
|
|
174
175
|
},
|
|
175
176
|
{
|
|
176
177
|
name: "flow_publish",
|
|
@@ -349,6 +350,47 @@ function buildDescriptors(deps = {}) {
|
|
|
349
350
|
});
|
|
350
351
|
},
|
|
351
352
|
},
|
|
353
|
+
{
|
|
354
|
+
name: "set_column",
|
|
355
|
+
annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
|
|
356
|
+
description: "Update the SCHEMA of an EXISTING column on an EXISTING ServiceNow table — its label, " +
|
|
357
|
+
"mandatory, default, readOnly, or maxLength — captured into a named update set, then READ " +
|
|
358
|
+
"BACK from the instance to verify. This is the schema counterpart to set_field: set_field " +
|
|
359
|
+
"changes a RECORD's value, set_column changes the COLUMN's definition (sys_dictionary). Use " +
|
|
360
|
+
"add_column to CREATE a column. maxLength is PHYSICAL — changing it fires a real ALTER on the " +
|
|
361
|
+
"table, and that works (verified live). internal_type and element (rename) are REFUSED, not " +
|
|
362
|
+
"written: ServiceNow returns HTTP 200 and silently ignores both on an existing column, so a " +
|
|
363
|
+
"write would report success while changing nothing — delete and recreate the column instead. " +
|
|
364
|
+
"Attributes are a closed set, never an open field map. When every requested value already " +
|
|
365
|
+
"matches, nothing is written and the status is 'unchanged' (an ALTER fires on a CHANGE, not a " +
|
|
366
|
+
"write). A maxLength SHRINK is REFUSED while rows hold longer values: ServiceNow silently " +
|
|
367
|
+
"refuses such a shrink (200 OK, column unchanged, data preserved), so the tool names the " +
|
|
368
|
+
"blocking rows instead of issuing a write that would be quietly ignored. Clear those values " +
|
|
369
|
+
"first, then re-run — there is no override, because forcing it would either do nothing or " +
|
|
370
|
+
"destroy data. dryRun:true diffs against the instance, flags the blocking rows, and writes nothing.",
|
|
371
|
+
shape: schemas_1.setColumnSchema.shape,
|
|
372
|
+
handler: async function (args) {
|
|
373
|
+
var p = schemas_1.setColumnSchema.parse(args);
|
|
374
|
+
// The schema leaves updateSetSysId optional (dry-run doesn't need one), so
|
|
375
|
+
// enforce the live-path requirement HERE — a tool-level error before any
|
|
376
|
+
// work beats a failure surfacing from deep inside setColumn. Same pattern
|
|
377
|
+
// as add_column.
|
|
378
|
+
if (p.dryRun !== true &&
|
|
379
|
+
(!p.updateSetSysId || !p.updateSetSysId.trim())) {
|
|
380
|
+
throw new Error("set_column: updateSetSysId is required on the live path so the schema " +
|
|
381
|
+
"change is captured in a known update set — set dryRun:true to plan " +
|
|
382
|
+
"without one.");
|
|
383
|
+
}
|
|
384
|
+
return (0, table_1.setColumn)({
|
|
385
|
+
client: client(),
|
|
386
|
+
table: p.table,
|
|
387
|
+
column: p.column,
|
|
388
|
+
attributes: p.attributes,
|
|
389
|
+
updateSetSysId: p.updateSetSysId,
|
|
390
|
+
dryRun: p.dryRun,
|
|
391
|
+
});
|
|
392
|
+
},
|
|
393
|
+
},
|
|
352
394
|
{
|
|
353
395
|
name: "set_field",
|
|
354
396
|
annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
|
package/dist/mcp/schemas.d.ts
CHANGED
|
@@ -830,6 +830,90 @@ export declare var addColumnSchema: z.ZodObject<{
|
|
|
830
830
|
scope?: string | undefined;
|
|
831
831
|
updateSetSysId?: string | undefined;
|
|
832
832
|
}>;
|
|
833
|
+
export declare var columnAttributesSchema: z.ZodObject<{
|
|
834
|
+
label: z.ZodOptional<z.ZodString>;
|
|
835
|
+
mandatory: z.ZodOptional<z.ZodBoolean>;
|
|
836
|
+
default: z.ZodOptional<z.ZodString>;
|
|
837
|
+
readOnly: z.ZodOptional<z.ZodBoolean>;
|
|
838
|
+
maxLength: z.ZodOptional<z.ZodNumber>;
|
|
839
|
+
internalType: z.ZodOptional<z.ZodString>;
|
|
840
|
+
element: z.ZodOptional<z.ZodString>;
|
|
841
|
+
}, "strip", z.ZodTypeAny, {
|
|
842
|
+
default?: string | undefined;
|
|
843
|
+
label?: string | undefined;
|
|
844
|
+
element?: string | undefined;
|
|
845
|
+
readOnly?: boolean | undefined;
|
|
846
|
+
maxLength?: number | undefined;
|
|
847
|
+
mandatory?: boolean | undefined;
|
|
848
|
+
internalType?: string | undefined;
|
|
849
|
+
}, {
|
|
850
|
+
default?: string | undefined;
|
|
851
|
+
label?: string | undefined;
|
|
852
|
+
element?: string | undefined;
|
|
853
|
+
readOnly?: boolean | undefined;
|
|
854
|
+
maxLength?: number | undefined;
|
|
855
|
+
mandatory?: boolean | undefined;
|
|
856
|
+
internalType?: string | undefined;
|
|
857
|
+
}>;
|
|
858
|
+
export declare var setColumnSchema: z.ZodObject<{
|
|
859
|
+
table: z.ZodString;
|
|
860
|
+
column: z.ZodString;
|
|
861
|
+
attributes: z.ZodObject<{
|
|
862
|
+
label: z.ZodOptional<z.ZodString>;
|
|
863
|
+
mandatory: z.ZodOptional<z.ZodBoolean>;
|
|
864
|
+
default: z.ZodOptional<z.ZodString>;
|
|
865
|
+
readOnly: z.ZodOptional<z.ZodBoolean>;
|
|
866
|
+
maxLength: z.ZodOptional<z.ZodNumber>;
|
|
867
|
+
internalType: z.ZodOptional<z.ZodString>;
|
|
868
|
+
element: z.ZodOptional<z.ZodString>;
|
|
869
|
+
}, "strip", z.ZodTypeAny, {
|
|
870
|
+
default?: string | undefined;
|
|
871
|
+
label?: string | undefined;
|
|
872
|
+
element?: string | undefined;
|
|
873
|
+
readOnly?: boolean | undefined;
|
|
874
|
+
maxLength?: number | undefined;
|
|
875
|
+
mandatory?: boolean | undefined;
|
|
876
|
+
internalType?: string | undefined;
|
|
877
|
+
}, {
|
|
878
|
+
default?: string | undefined;
|
|
879
|
+
label?: string | undefined;
|
|
880
|
+
element?: string | undefined;
|
|
881
|
+
readOnly?: boolean | undefined;
|
|
882
|
+
maxLength?: number | undefined;
|
|
883
|
+
mandatory?: boolean | undefined;
|
|
884
|
+
internalType?: string | undefined;
|
|
885
|
+
}>;
|
|
886
|
+
updateSetSysId: z.ZodOptional<z.ZodString>;
|
|
887
|
+
dryRun: z.ZodOptional<z.ZodBoolean>;
|
|
888
|
+
}, "strip", z.ZodTypeAny, {
|
|
889
|
+
table: string;
|
|
890
|
+
attributes: {
|
|
891
|
+
default?: string | undefined;
|
|
892
|
+
label?: string | undefined;
|
|
893
|
+
element?: string | undefined;
|
|
894
|
+
readOnly?: boolean | undefined;
|
|
895
|
+
maxLength?: number | undefined;
|
|
896
|
+
mandatory?: boolean | undefined;
|
|
897
|
+
internalType?: string | undefined;
|
|
898
|
+
};
|
|
899
|
+
column: string;
|
|
900
|
+
dryRun?: boolean | undefined;
|
|
901
|
+
updateSetSysId?: string | undefined;
|
|
902
|
+
}, {
|
|
903
|
+
table: string;
|
|
904
|
+
attributes: {
|
|
905
|
+
default?: string | undefined;
|
|
906
|
+
label?: string | undefined;
|
|
907
|
+
element?: string | undefined;
|
|
908
|
+
readOnly?: boolean | undefined;
|
|
909
|
+
maxLength?: number | undefined;
|
|
910
|
+
mandatory?: boolean | undefined;
|
|
911
|
+
internalType?: string | undefined;
|
|
912
|
+
};
|
|
913
|
+
column: string;
|
|
914
|
+
dryRun?: boolean | undefined;
|
|
915
|
+
updateSetSysId?: string | undefined;
|
|
916
|
+
}>;
|
|
833
917
|
export declare var setFieldSchema: z.ZodObject<{
|
|
834
918
|
table: z.ZodString;
|
|
835
919
|
sysId: z.ZodOptional<z.ZodString>;
|