@tenonhq/dovetail-servicenow 0.0.24 → 0.0.25
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/README.md +71 -2
- package/dist/client.d.ts +2 -2
- package/dist/createRecord.d.ts +2 -8
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -1
- package/dist/mcp/registry.d.ts +1 -1
- package/dist/mcp/registry.js +54 -0
- package/dist/mcp/schemas.d.ts +44 -0
- package/dist/mcp/schemas.js +21 -1
- package/dist/setField.d.ts +14 -5
- package/dist/setField.js +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -253,6 +253,72 @@ adds diagnostics (app-switch status, resolved column key, assigned sys_id) to th
|
|
|
253
253
|
result note. Ground truth (the HAR dissection) lives in the CTO repo's create-table
|
|
254
254
|
docs.
|
|
255
255
|
|
|
256
|
+
### Set a field on a record
|
|
257
|
+
|
|
258
|
+
Set scalar field value(s) on an **existing** data record, capture the change into
|
|
259
|
+
an update set, then read it back and verify.
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Target by sys_id
|
|
263
|
+
npx dove-sn set-field \
|
|
264
|
+
--table x_cadso_core_metric_point_type --sys-id <sys_id> \
|
|
265
|
+
--fields "order=20" --update-set <sys_id> --dry-run --json
|
|
266
|
+
|
|
267
|
+
# Or target by a query that resolves to EXACTLY one row
|
|
268
|
+
npx dove-sn set-field \
|
|
269
|
+
--table x_cadso_core_metric_point_type --query "name=send_size" \
|
|
270
|
+
--fields "order=20,label=Send Size" --update-set <sys_id>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
`set-field` wraps the update-set-aware `pushWithUpdateSet` core op (update-set +
|
|
274
|
+
scope switching handled server-side, so no `sys_user_preference` is touched), then
|
|
275
|
+
re-queries the record and verifies each value landed. It **refuses** schema tables
|
|
276
|
+
(`sys_db_object` / `sys_dictionary`) — use `add-column` / `create-table` for those.
|
|
277
|
+
`--fields` is a comma-separated `key=value` map (values are sent as strings;
|
|
278
|
+
ServiceNow coerces); `--update-set` is required so the change is captured;
|
|
279
|
+
`--dry-run` reads the current values and prints the plan without writing. Exit
|
|
280
|
+
codes: `0` applied / dry-run, `1` bad args, `2` write landed but read-back did not
|
|
281
|
+
verify.
|
|
282
|
+
|
|
283
|
+
### Create a record
|
|
284
|
+
|
|
285
|
+
Insert **one** new data record, owned by an explicit scope and captured into an
|
|
286
|
+
update set, then read it back and verify.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
npx dove-sn create-record \
|
|
290
|
+
--table x_cadso_core_metric_point_type \
|
|
291
|
+
--fields "name=avg_message_parts,label=Avg. Message Parts,order=35" \
|
|
292
|
+
--scope x_cadso_core --update-set <sys_id> \
|
|
293
|
+
--if-absent "name=avg_message_parts" --dry-run --json
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
`create-record` wraps the scope- and update-set-aware `createRecord` core op, which
|
|
297
|
+
switches the executing user's app scope + update set server-side, inserts, and
|
|
298
|
+
restores both — so the record is owned by the right app and the insert is captured
|
|
299
|
+
in the right update set. Like `set-field` it **refuses** schema tables and verifies
|
|
300
|
+
via read-back. `--scope` and `--update-set` are required; `--if-absent
|
|
301
|
+
"<encoded-query>"` makes re-runs idempotent (the insert is skipped when the query
|
|
302
|
+
already matches a row). Exit codes: `0` created / skipped-in-sync / dry-run, `1` bad
|
|
303
|
+
args, `2` write landed unverified (or skipped with drift). To **update** an existing
|
|
304
|
+
record instead, use `set-field`.
|
|
305
|
+
|
|
306
|
+
Both verbs are exported for programmatic use:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import { createClient, setField, createRecord } from "@tenonhq/dovetail-servicenow";
|
|
310
|
+
|
|
311
|
+
var client = createClient({});
|
|
312
|
+
var r = await setField({
|
|
313
|
+
client: client,
|
|
314
|
+
table: "x_cadso_core_metric_point_type",
|
|
315
|
+
sysId: "<sys_id>",
|
|
316
|
+
fields: { order: "20" },
|
|
317
|
+
updateSetSysId: "<sys_id>"
|
|
318
|
+
});
|
|
319
|
+
console.log(r.status, r.verified); // "applied" true
|
|
320
|
+
```
|
|
321
|
+
|
|
256
322
|
`test-flow` defaults to **validate** — a safe pre-flight (published? inputs match
|
|
257
323
|
declared variables?) that never runs the flow; `--execute --confirm` runs it via
|
|
258
324
|
the server-side FlowAPI runner (deploy `resources/runFlow.md` first).
|
|
@@ -323,8 +389,11 @@ console.log(formatLayoutResult("form layout", result));
|
|
|
323
389
|
|
|
324
390
|
`dove-sn mcp` runs a self-contained MCP stdio server exposing the tools to
|
|
325
391
|
Claude Code and agents: `create_view`, `set_list_layout`, `set_form_layout`,
|
|
326
|
-
`set_related_lists`, `add_choices_to_field`,
|
|
327
|
-
`
|
|
392
|
+
`set_related_lists`, `add_choices_to_field`, the schema verbs `create_table` /
|
|
393
|
+
`add_column`, the record-write verbs `set_field` (update scalar fields on an
|
|
394
|
+
existing record) and `create_record` (insert one record) — both update-set-captured
|
|
395
|
+
and read-back-verified — `host_assets` (deploy a built dist/), plus the Flow Designer
|
|
396
|
+
tools `flow_view` (read a flow/subflow's step graph), `action_view` (read an action
|
|
328
397
|
type's model), `flow_publish` (compile a flow/subflow snapshot), `flow_copy`
|
|
329
398
|
(copy a flow as an inactive draft), `flow_create` (create a NEW flow from scratch +
|
|
330
399
|
publish, grafting a template), `flow_test` (validate or run a flow), and
|
package/dist/client.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ export interface ServiceNowClient {
|
|
|
74
74
|
/** POST /api/cadso/dovetail_core/createRecord (legacy: /api/cadso/dovetail/createRecord). */
|
|
75
75
|
createRecord: (params: {
|
|
76
76
|
table: string;
|
|
77
|
-
fields: Record<string,
|
|
77
|
+
fields: Record<string, unknown>;
|
|
78
78
|
scope?: string;
|
|
79
79
|
update_set_sys_id?: string;
|
|
80
80
|
sys_id?: string;
|
|
@@ -87,7 +87,7 @@ export interface ServiceNowClient {
|
|
|
87
87
|
update_set_sys_id: string;
|
|
88
88
|
table: string;
|
|
89
89
|
record_sys_id: string;
|
|
90
|
-
fields: Record<string,
|
|
90
|
+
fields: Record<string, unknown>;
|
|
91
91
|
}) => Promise<{
|
|
92
92
|
sys_id: string;
|
|
93
93
|
[k: string]: any;
|
package/dist/createRecord.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* create-table / add-column. To UPDATE an existing record, use `set-field`.
|
|
13
13
|
*/
|
|
14
14
|
import type { ServiceNowClient } from "./client";
|
|
15
|
+
import type { RecordWriteResult } from "./setField";
|
|
15
16
|
export interface CreateRecordParams {
|
|
16
17
|
client?: ServiceNowClient;
|
|
17
18
|
table: string;
|
|
@@ -25,15 +26,8 @@ export interface CreateRecordParams {
|
|
|
25
26
|
ifAbsentQuery?: string;
|
|
26
27
|
dryRun?: boolean;
|
|
27
28
|
}
|
|
28
|
-
export interface CreateRecordResult {
|
|
29
|
+
export interface CreateRecordResult extends RecordWriteResult {
|
|
29
30
|
status: "dry-run" | "created" | "skipped" | "failed";
|
|
30
|
-
table: string;
|
|
31
|
-
sysId: string;
|
|
32
31
|
scope: string;
|
|
33
|
-
updateSetSysId: string;
|
|
34
|
-
fields: Record<string, string>;
|
|
35
|
-
after: Record<string, string>;
|
|
36
|
-
verified: boolean;
|
|
37
|
-
note: string;
|
|
38
32
|
}
|
|
39
33
|
export declare function createRecord(params: CreateRecordParams): Promise<CreateRecordResult>;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,3 +21,7 @@ export type { TemplateRef, ListTemplatesParams, FlowKind, VerifyExpect, VerifyFo
|
|
|
21
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
22
|
export { createTable, projectTableGraph, buildColumnXml, normalizeColumns, resolveType, applyTableSaveOverlay, defaultAccessFlags, TYPE_MAP, DEFAULT_SUPER_CLASS, DEFAULT_SAVE_ACTION, addColumn, deriveElement, applyAddColumnOverlay } from "./table";
|
|
23
23
|
export type { CreateTableParams, CreateTableResult, AddColumnParams, AddColumnResult, TableGraph, NormalizedColumn, ColumnSpec, AccessFlags, OverlaySpec } from "./table";
|
|
24
|
+
export { setField } from "./setField";
|
|
25
|
+
export { createRecord } from "./createRecord";
|
|
26
|
+
export type { RecordWriteResult, SetFieldParams, SetFieldResult } from "./setField";
|
|
27
|
+
export type { CreateRecordParams, CreateRecordResult } from "./createRecord";
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* REST API so every change lands in the target update set and scope.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.applyAddColumnOverlay = exports.deriveElement = 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.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;
|
|
9
|
+
exports.createRecord = exports.setField = exports.applyAddColumnOverlay = exports.deriveElement = 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.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
10
|
var client_1 = require("./client");
|
|
11
11
|
Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return client_1.createClient; } });
|
|
12
12
|
var createClientFromEnvFile_1 = require("./createClientFromEnvFile");
|
|
@@ -68,3 +68,7 @@ Object.defineProperty(exports, "DEFAULT_SAVE_ACTION", { enumerable: true, get: f
|
|
|
68
68
|
Object.defineProperty(exports, "addColumn", { enumerable: true, get: function () { return table_1.addColumn; } });
|
|
69
69
|
Object.defineProperty(exports, "deriveElement", { enumerable: true, get: function () { return table_1.deriveElement; } });
|
|
70
70
|
Object.defineProperty(exports, "applyAddColumnOverlay", { enumerable: true, get: function () { return table_1.applyAddColumnOverlay; } });
|
|
71
|
+
var setField_1 = require("./setField");
|
|
72
|
+
Object.defineProperty(exports, "setField", { enumerable: true, get: function () { return setField_1.setField; } });
|
|
73
|
+
var createRecord_1 = require("./createRecord");
|
|
74
|
+
Object.defineProperty(exports, "createRecord", { enumerable: true, get: function () { return createRecord_1.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", "flow_publish", "flow_copy", "flow_create", "flow_test", "flow_edit", "create_table", "add_column", "host_assets"];
|
|
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", "flow_publish", "flow_copy", "flow_create", "flow_test", "flow_edit", "create_table", "add_column", "set_field", "create_record", "host_assets"];
|
|
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
|
@@ -27,6 +27,8 @@ const editFlow_1 = require("../flowDesigner/editFlow");
|
|
|
27
27
|
const testFlow_1 = require("../flowDesigner/testFlow");
|
|
28
28
|
const table_1 = require("../table");
|
|
29
29
|
const hostAssets_1 = require("../hostAssets");
|
|
30
|
+
const setField_1 = require("../setField");
|
|
31
|
+
const createRecord_1 = require("../createRecord");
|
|
30
32
|
const schemas_1 = require("./schemas");
|
|
31
33
|
exports.TOOL_NAMES = [
|
|
32
34
|
"create_view",
|
|
@@ -43,6 +45,8 @@ exports.TOOL_NAMES = [
|
|
|
43
45
|
"flow_edit",
|
|
44
46
|
"create_table",
|
|
45
47
|
"add_column",
|
|
48
|
+
"set_field",
|
|
49
|
+
"create_record",
|
|
46
50
|
"host_assets"
|
|
47
51
|
];
|
|
48
52
|
// Annotation presets (READ_ONLY / WRITE_ADDITIVE_IDEMPOTENT / WRITE_CREATE /
|
|
@@ -296,6 +300,56 @@ function buildDescriptors(deps = {}) {
|
|
|
296
300
|
});
|
|
297
301
|
}
|
|
298
302
|
},
|
|
303
|
+
{
|
|
304
|
+
name: "set_field",
|
|
305
|
+
annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
|
|
306
|
+
description: "Set scalar field value(s) on an EXISTING ServiceNow data record, captured into a specified "
|
|
307
|
+
+ "update set, then READ BACK to verify each value landed. Wraps the update-set-aware "
|
|
308
|
+
+ "pushWithUpdateSet core op (no sys_user_preference mutation). Target the record by sysId, or "
|
|
309
|
+
+ "by a query that resolves to EXACTLY one row. REFUSES schema tables (sys_db_object / "
|
|
310
|
+
+ "sys_dictionary) — use add_column / create_table for those. fields is a flat name->string map "
|
|
311
|
+
+ "(sent as strings; ServiceNow coerces); updateSetSysId is required so the change is tracked; "
|
|
312
|
+
+ "dryRun:true reads the current values and returns the plan without writing. To INSERT a new "
|
|
313
|
+
+ "record use create_record.",
|
|
314
|
+
shape: schemas_1.setFieldSchema.shape,
|
|
315
|
+
handler: async function (args) {
|
|
316
|
+
var p = schemas_1.setFieldSchema.parse(args);
|
|
317
|
+
return (0, setField_1.setField)({
|
|
318
|
+
client: client(),
|
|
319
|
+
table: p.table,
|
|
320
|
+
sysId: p.sysId,
|
|
321
|
+
query: p.query,
|
|
322
|
+
fields: p.fields,
|
|
323
|
+
updateSetSysId: p.updateSetSysId,
|
|
324
|
+
dryRun: p.dryRun
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "create_record",
|
|
330
|
+
annotations: dovetail_mcp_kit_1.WRITE_CREATE,
|
|
331
|
+
description: "Create ONE new ServiceNow data record, owned by an explicit app scope and captured into a "
|
|
332
|
+
+ "specified update set, then READ BACK to verify. Wraps the scope- and update-set-aware "
|
|
333
|
+
+ "createRecord core op (switches app scope + update set server-side, inserts, restores both — "
|
|
334
|
+
+ "so the record lands in the right scope without sys_user_preference mutation). REFUSES schema "
|
|
335
|
+
+ "tables (sys_db_object / sys_dictionary) — use create_table / add_column for those. fields is a "
|
|
336
|
+
+ "flat name->string map; scope and updateSetSysId are required; ifAbsentQuery makes re-runs "
|
|
337
|
+
+ "idempotent (skips the insert when it already matches a row); dryRun:true returns the plan "
|
|
338
|
+
+ "without writing. To UPDATE an existing record use set_field.",
|
|
339
|
+
shape: schemas_1.createRecordSchema.shape,
|
|
340
|
+
handler: async function (args) {
|
|
341
|
+
var p = schemas_1.createRecordSchema.parse(args);
|
|
342
|
+
return (0, createRecord_1.createRecord)({
|
|
343
|
+
client: client(),
|
|
344
|
+
table: p.table,
|
|
345
|
+
fields: p.fields,
|
|
346
|
+
scope: p.scope,
|
|
347
|
+
updateSetSysId: p.updateSetSysId,
|
|
348
|
+
ifAbsentQuery: p.ifAbsentQuery,
|
|
349
|
+
dryRun: p.dryRun
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
},
|
|
299
353
|
{
|
|
300
354
|
name: "host_assets",
|
|
301
355
|
annotations: dovetail_mcp_kit_1.WRITE_OVERWRITE,
|
package/dist/mcp/schemas.d.ts
CHANGED
|
@@ -563,3 +563,47 @@ export declare var addColumnSchema: z.ZodObject<{
|
|
|
563
563
|
saveActionSysId?: string | undefined;
|
|
564
564
|
columnsRelId?: string | undefined;
|
|
565
565
|
}>;
|
|
566
|
+
export declare var setFieldSchema: z.ZodObject<{
|
|
567
|
+
table: z.ZodString;
|
|
568
|
+
sysId: z.ZodOptional<z.ZodString>;
|
|
569
|
+
query: z.ZodOptional<z.ZodString>;
|
|
570
|
+
fields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
571
|
+
updateSetSysId: z.ZodString;
|
|
572
|
+
dryRun: z.ZodOptional<z.ZodBoolean>;
|
|
573
|
+
}, "strip", z.ZodTypeAny, {
|
|
574
|
+
table: string;
|
|
575
|
+
fields: Record<string, string>;
|
|
576
|
+
updateSetSysId: string;
|
|
577
|
+
query?: string | undefined;
|
|
578
|
+
sysId?: string | undefined;
|
|
579
|
+
dryRun?: boolean | undefined;
|
|
580
|
+
}, {
|
|
581
|
+
table: string;
|
|
582
|
+
fields: Record<string, string>;
|
|
583
|
+
updateSetSysId: string;
|
|
584
|
+
query?: string | undefined;
|
|
585
|
+
sysId?: string | undefined;
|
|
586
|
+
dryRun?: boolean | undefined;
|
|
587
|
+
}>;
|
|
588
|
+
export declare var createRecordSchema: z.ZodObject<{
|
|
589
|
+
table: z.ZodString;
|
|
590
|
+
fields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
591
|
+
scope: z.ZodString;
|
|
592
|
+
updateSetSysId: z.ZodString;
|
|
593
|
+
ifAbsentQuery: z.ZodOptional<z.ZodString>;
|
|
594
|
+
dryRun: z.ZodOptional<z.ZodBoolean>;
|
|
595
|
+
}, "strip", z.ZodTypeAny, {
|
|
596
|
+
table: string;
|
|
597
|
+
fields: Record<string, string>;
|
|
598
|
+
scope: string;
|
|
599
|
+
updateSetSysId: string;
|
|
600
|
+
dryRun?: boolean | undefined;
|
|
601
|
+
ifAbsentQuery?: string | undefined;
|
|
602
|
+
}, {
|
|
603
|
+
table: string;
|
|
604
|
+
fields: Record<string, string>;
|
|
605
|
+
scope: string;
|
|
606
|
+
updateSetSysId: string;
|
|
607
|
+
dryRun?: boolean | undefined;
|
|
608
|
+
ifAbsentQuery?: string | undefined;
|
|
609
|
+
}>;
|
package/dist/mcp/schemas.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* own file so registry.ts stays focused on wiring.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.addColumnSchema = exports.createTableSchema = exports.columnSpecSchema = exports.hostAssetsSchema = exports.editFlowSchema = exports.stepInputPatchSchema = exports.testFlowSchema = exports.createFlowSchema = exports.copyFlowSchema = exports.publishFlowSchema = exports.viewActionSchema = exports.viewFlowSchema = exports.addChoicesToFieldSchema = exports.choiceValueSchema = exports.setRelatedListsSchema = exports.setFormLayoutSchema = exports.formSectionSchema = exports.setListLayoutSchema = exports.createViewSchema = void 0;
|
|
7
|
+
exports.createRecordSchema = exports.setFieldSchema = exports.addColumnSchema = exports.createTableSchema = exports.columnSpecSchema = exports.hostAssetsSchema = exports.editFlowSchema = exports.stepInputPatchSchema = exports.testFlowSchema = exports.createFlowSchema = exports.copyFlowSchema = exports.publishFlowSchema = exports.viewActionSchema = exports.viewFlowSchema = exports.addChoicesToFieldSchema = exports.choiceValueSchema = exports.setRelatedListsSchema = exports.setFormLayoutSchema = exports.formSectionSchema = exports.setListLayoutSchema = exports.createViewSchema = void 0;
|
|
8
8
|
const zod_1 = require("zod");
|
|
9
9
|
exports.createViewSchema = zod_1.z.object({
|
|
10
10
|
name: zod_1.z.string().min(1),
|
|
@@ -156,3 +156,23 @@ exports.addColumnSchema = zod_1.z.object({
|
|
|
156
156
|
dryRun: zod_1.z.boolean().optional(),
|
|
157
157
|
debug: zod_1.z.boolean().optional()
|
|
158
158
|
});
|
|
159
|
+
// Data-record write verbs. Kept as plain z.object (no .refine wrapper) so
|
|
160
|
+
// registry.ts can read `.shape`; the deeper rules — one of sysId/query, at
|
|
161
|
+
// least one field, the schema-table refusal — are enforced by the core
|
|
162
|
+
// setField / createRecord functions, which throw clear errors.
|
|
163
|
+
exports.setFieldSchema = zod_1.z.object({
|
|
164
|
+
table: zod_1.z.string().min(1),
|
|
165
|
+
sysId: zod_1.z.string().optional(),
|
|
166
|
+
query: zod_1.z.string().optional(),
|
|
167
|
+
fields: zod_1.z.record(zod_1.z.string()),
|
|
168
|
+
updateSetSysId: zod_1.z.string().min(1),
|
|
169
|
+
dryRun: zod_1.z.boolean().optional()
|
|
170
|
+
});
|
|
171
|
+
exports.createRecordSchema = zod_1.z.object({
|
|
172
|
+
table: zod_1.z.string().min(1),
|
|
173
|
+
fields: zod_1.z.record(zod_1.z.string()),
|
|
174
|
+
scope: zod_1.z.string().min(1),
|
|
175
|
+
updateSetSysId: zod_1.z.string().min(1),
|
|
176
|
+
ifAbsentQuery: zod_1.z.string().optional(),
|
|
177
|
+
dryRun: zod_1.z.boolean().optional()
|
|
178
|
+
});
|
package/dist/setField.d.ts
CHANGED
|
@@ -23,19 +23,28 @@ export interface SetFieldParams {
|
|
|
23
23
|
updateSetSysId?: string;
|
|
24
24
|
dryRun?: boolean;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Fields common to every record-write verb's result: the target, the update set
|
|
28
|
+
* the change was captured into, the requested field map, the read-back values,
|
|
29
|
+
* whether the read-back matched, and a human note. `set-field` and
|
|
30
|
+
* `create-record` each extend this with their own `status` union (and
|
|
31
|
+
* set-field's `before` snapshot / create-record's owning `scope`).
|
|
32
|
+
*/
|
|
33
|
+
export interface RecordWriteResult {
|
|
28
34
|
table: string;
|
|
29
35
|
sysId: string;
|
|
30
36
|
updateSetSysId: string;
|
|
31
37
|
fields: Record<string, string>;
|
|
32
|
-
before: Record<string, string>;
|
|
33
38
|
after: Record<string, string>;
|
|
34
39
|
verified: boolean;
|
|
35
40
|
note: string;
|
|
36
41
|
}
|
|
42
|
+
export interface SetFieldResult extends RecordWriteResult {
|
|
43
|
+
status: "dry-run" | "applied" | "failed";
|
|
44
|
+
before: Record<string, string>;
|
|
45
|
+
}
|
|
37
46
|
/** Coerce a Table-API field value to a comparable string. Reference/display
|
|
38
47
|
* fields (sysparm_display_value=false) come back as { link, value } objects. */
|
|
39
|
-
export declare function fieldToString(value:
|
|
40
|
-
export declare function pickFields(row: Record<string,
|
|
48
|
+
export declare function fieldToString(value: unknown): string;
|
|
49
|
+
export declare function pickFields(row: Record<string, unknown>, names: Array<string>): Record<string, string>;
|
|
41
50
|
export declare function setField(params: SetFieldParams): Promise<SetFieldResult>;
|
package/dist/setField.js
CHANGED
|
@@ -25,7 +25,10 @@ function fieldToString(value) {
|
|
|
25
25
|
if (value === undefined || value === null)
|
|
26
26
|
return "";
|
|
27
27
|
if (typeof value === "object") {
|
|
28
|
-
|
|
28
|
+
if ("value" in value && value.value !== undefined && value.value !== null) {
|
|
29
|
+
return String(value.value);
|
|
30
|
+
}
|
|
31
|
+
return "";
|
|
29
32
|
}
|
|
30
33
|
return String(value);
|
|
31
34
|
}
|