@sonisoft/now-sdk-ext-core 6.12.0 → 6.14.0
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/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/sn/metadata/ChoiceWriter.d.ts +39 -0
- package/dist/sn/metadata/ChoiceWriter.js +435 -0
- package/dist/sn/metadata/ChoiceWriter.js.map +1 -0
- package/dist/sn/metadata/ColumnWriter.js +1 -30
- package/dist/sn/metadata/ColumnWriter.js.map +1 -1
- package/dist/sn/metadata/MetadataFormWriter.js +3 -10
- package/dist/sn/metadata/MetadataFormWriter.js.map +1 -1
- package/dist/sn/metadata/MetadataModels.d.ts +101 -0
- package/dist/sn/metadata/MetadataScopeError.d.ts +4 -2
- package/dist/sn/metadata/MetadataScopeError.js +2 -0
- package/dist/sn/metadata/MetadataScopeError.js.map +1 -1
- package/dist/sn/metadata/internal/MetadataFormActions.d.ts +6 -0
- package/dist/sn/metadata/internal/MetadataFormActions.js +19 -0
- package/dist/sn/metadata/internal/MetadataFormActions.js.map +1 -0
- package/dist/sn/metadata/internal/MetadataTables.d.ts +8 -0
- package/dist/sn/metadata/internal/MetadataTables.js +34 -0
- package/dist/sn/metadata/internal/MetadataTables.js.map +1 -0
- package/dist/sn/updateset/UpdateSetExportModels.d.ts +70 -0
- package/dist/sn/updateset/UpdateSetExportModels.js +14 -0
- package/dist/sn/updateset/UpdateSetExportModels.js.map +1 -0
- package/dist/sn/updateset/UpdateSetExporter.d.ts +60 -0
- package/dist/sn/updateset/UpdateSetExporter.js +365 -0
- package/dist/sn/updateset/UpdateSetExporter.js.map +1 -0
- package/dist/sn/updateset/UpdateSetManager.d.ts +6 -5
- package/dist/sn/updateset/UpdateSetManager.js +10 -71
- package/dist/sn/updateset/UpdateSetManager.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export * from './sn/health/HealthModels.js';
|
|
|
86
86
|
export * from './sn/health/InstanceHealth.js';
|
|
87
87
|
export * from './sn/knowledge/KnowledgeManager.js';
|
|
88
88
|
export * from './sn/knowledge/KnowledgeModels.js';
|
|
89
|
+
export * from './sn/metadata/ChoiceWriter.js';
|
|
89
90
|
export * from './sn/metadata/ColumnWriter.js';
|
|
90
91
|
export * from './sn/metadata/FormLayoutWriter.js';
|
|
91
92
|
export * from './sn/metadata/ListLayoutWriter.js';
|
|
@@ -108,6 +109,8 @@ export * from './sn/task/TaskModels.js';
|
|
|
108
109
|
export * from './sn/task/TaskOperations.js';
|
|
109
110
|
export * from './sn/transaction/ClusterTransactionManager.js';
|
|
110
111
|
export * from './sn/transaction/ClusterTransactionModels.js';
|
|
112
|
+
export * from './sn/updateset/UpdateSetExporter.js';
|
|
113
|
+
export * from './sn/updateset/UpdateSetExportModels.js';
|
|
111
114
|
export * from './sn/updateset/UpdateSetManager.js';
|
|
112
115
|
export * from './sn/updateset/UpdateSetModels.js';
|
|
113
116
|
export * from './sn/updateset/WorkingSetManager.js';
|
package/dist/index.js
CHANGED
|
@@ -86,6 +86,7 @@ export * from './sn/health/HealthModels.js';
|
|
|
86
86
|
export * from './sn/health/InstanceHealth.js';
|
|
87
87
|
export * from './sn/knowledge/KnowledgeManager.js';
|
|
88
88
|
export * from './sn/knowledge/KnowledgeModels.js';
|
|
89
|
+
export * from './sn/metadata/ChoiceWriter.js';
|
|
89
90
|
export * from './sn/metadata/ColumnWriter.js';
|
|
90
91
|
export * from './sn/metadata/FormLayoutWriter.js';
|
|
91
92
|
export * from './sn/metadata/ListLayoutWriter.js';
|
|
@@ -108,6 +109,8 @@ export * from './sn/task/TaskModels.js';
|
|
|
108
109
|
export * from './sn/task/TaskOperations.js';
|
|
109
110
|
export * from './sn/transaction/ClusterTransactionManager.js';
|
|
110
111
|
export * from './sn/transaction/ClusterTransactionModels.js';
|
|
112
|
+
export * from './sn/updateset/UpdateSetExporter.js';
|
|
113
|
+
export * from './sn/updateset/UpdateSetExportModels.js';
|
|
111
114
|
export * from './sn/updateset/UpdateSetManager.js';
|
|
112
115
|
export * from './sn/updateset/UpdateSetModels.js';
|
|
113
116
|
export * from './sn/updateset/WorkingSetManager.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ServiceNowInstance } from '../ServiceNowInstance.js';
|
|
2
|
+
import type { ChoiceList, ChoiceListOptions, ChoiceRemoveOptions, ChoiceWriteOptions, ChoiceWriteResult } from './MetadataModels.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adds, changes and removes a column's choices through the choice form (`sys_choice.do`), the path the platform itself
|
|
5
|
+
* uses, and verifies what the platform did. Seen on dev206299:
|
|
6
|
+
*
|
|
7
|
+
* - A sys_choice row has no application. The list's application file is its sys_choice_set (one per table and column),
|
|
8
|
+
* which the platform creates with the list's first choice, in the form's application.
|
|
9
|
+
* - Every change rewrites one capture, `sys_choice_<table>_<element>` (type Choice list), holding the choice set and
|
|
10
|
+
* every choice of the list. It goes to the update set posted with the form, which need not be the user's current set.
|
|
11
|
+
* Removing the list's last choice keeps the choice set; the capture then holds it with no choices.
|
|
12
|
+
* - The form's Table field only offers the application's own tables (and tables it may alter). Loaded in another
|
|
13
|
+
* application it comes back empty, and posting it saves a choice with no table, captured as `sys_choice__<element>`.
|
|
14
|
+
* The writer refuses before posting when the loaded form does not name the table.
|
|
15
|
+
*
|
|
16
|
+
* The writer never changes the user's working set or current application. The Table API is not used: it inserts in the
|
|
17
|
+
* session's current application and refuses another application's table.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ChoiceWriter {
|
|
20
|
+
private _instance;
|
|
21
|
+
constructor(_instance: ServiceNowInstance);
|
|
22
|
+
/** The column's choice list in one language, with the column's dictionary setting and the list's application file. */
|
|
23
|
+
getChoices(table: string, element: string, options?: ChoiceListOptions): Promise<ChoiceList>;
|
|
24
|
+
/**
|
|
25
|
+
* Add the choice `options.value` (with `options.label`), or change the label, sequence, inactive flag or hint of the
|
|
26
|
+
* existing choice with that value. Reordering is a sequence change; inactivating keeps the choice for records that hold it.
|
|
27
|
+
*/
|
|
28
|
+
setChoice(table: string, element: string, options: ChoiceWriteOptions): Promise<ChoiceWriteResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove the choice `options.value`. Refused while records hold the value unless `options.confirmInUse` is set; the
|
|
31
|
+
* records keep the value either way.
|
|
32
|
+
*/
|
|
33
|
+
removeChoice(table: string, element: string, options: ChoiceRemoveOptions): Promise<ChoiceWriteResult>;
|
|
34
|
+
private request;
|
|
35
|
+
private context;
|
|
36
|
+
private write;
|
|
37
|
+
/** Records holding a value, from the Stats API: a paged read is bounded, a count is not. */
|
|
38
|
+
private count;
|
|
39
|
+
}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { Parser } from 'xml2js';
|
|
3
|
+
import { InvalidParameterException } from '../../exception/InvalidParameterException.js';
|
|
4
|
+
import { FormSubmitError } from '../../exception/FormSubmitError.js';
|
|
5
|
+
import { createFormTransport } from '../../comm/http/FormRecordWriter.js';
|
|
6
|
+
import { SessionManager } from '../../comm/http/SessionManager.js';
|
|
7
|
+
import { READ_ONLY } from '../../policy/PolicyTypes.js';
|
|
8
|
+
import { isPolicyRefusal } from '../../policy/PolicyRefusal.js';
|
|
9
|
+
import { stripSecretsFromError } from '../../util/redact.js';
|
|
10
|
+
import { MetadataScopeError } from './MetadataScopeError.js';
|
|
11
|
+
import { MetadataVerificationError } from './MetadataVerificationError.js';
|
|
12
|
+
import { MetadataReader } from './internal/MetadataReader.js';
|
|
13
|
+
import { comparePreferences } from './internal/MetadataPreferences.js';
|
|
14
|
+
import { customizationEvidence, resolveScope } from './internal/MetadataScope.js';
|
|
15
|
+
import { ancestry } from './internal/MetadataTables.js';
|
|
16
|
+
import { requirePlatformDelete } from './internal/MetadataFormActions.js';
|
|
17
|
+
const ID = /^[a-f0-9]{32}$/i;
|
|
18
|
+
const NAME = /^[a-z0-9_]+$/i;
|
|
19
|
+
const LANGUAGE = /^[a-z][a-z_]{1,9}$/i;
|
|
20
|
+
// eslint-disable-next-line no-control-regex
|
|
21
|
+
const CONTROL = /[\u0000-\u001f\u007f-\u009f]/;
|
|
22
|
+
const CHOICE = 'sys_choice';
|
|
23
|
+
const CHOICE_FIELDS = 'sys_id,name,element,language,value,label,sequence,inactive,hint,dependent_value';
|
|
24
|
+
/** The fields a Choice list capture carries for each choice and that a commit applies on the target. */
|
|
25
|
+
const CAPTURED_FIELDS = ['value', 'label', 'sequence', 'inactive', 'hint', 'language', 'dependent_value'];
|
|
26
|
+
const MAX_SEQUENCE = 2 ** 31 - 1;
|
|
27
|
+
/**
|
|
28
|
+
* Adds, changes and removes a column's choices through the choice form (`sys_choice.do`), the path the platform itself
|
|
29
|
+
* uses, and verifies what the platform did. Seen on dev206299:
|
|
30
|
+
*
|
|
31
|
+
* - A sys_choice row has no application. The list's application file is its sys_choice_set (one per table and column),
|
|
32
|
+
* which the platform creates with the list's first choice, in the form's application.
|
|
33
|
+
* - Every change rewrites one capture, `sys_choice_<table>_<element>` (type Choice list), holding the choice set and
|
|
34
|
+
* every choice of the list. It goes to the update set posted with the form, which need not be the user's current set.
|
|
35
|
+
* Removing the list's last choice keeps the choice set; the capture then holds it with no choices.
|
|
36
|
+
* - The form's Table field only offers the application's own tables (and tables it may alter). Loaded in another
|
|
37
|
+
* application it comes back empty, and posting it saves a choice with no table, captured as `sys_choice__<element>`.
|
|
38
|
+
* The writer refuses before posting when the loaded form does not name the table.
|
|
39
|
+
*
|
|
40
|
+
* The writer never changes the user's working set or current application. The Table API is not used: it inserts in the
|
|
41
|
+
* session's current application and refuses another application's table.
|
|
42
|
+
*/
|
|
43
|
+
export class ChoiceWriter {
|
|
44
|
+
_instance;
|
|
45
|
+
constructor(_instance) {
|
|
46
|
+
this._instance = _instance;
|
|
47
|
+
}
|
|
48
|
+
/** The column's choice list in one language, with the column's dictionary setting and the list's application file. */
|
|
49
|
+
async getChoices(table, element, options = {}) {
|
|
50
|
+
const language = options?.language ?? 'en';
|
|
51
|
+
if (!NAME.test(table ?? '') || !NAME.test(element ?? '') || typeof language !== 'string' || !LANGUAGE.test(language)) {
|
|
52
|
+
throw new MetadataScopeError('invalid_input');
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const context = await this.context(new MetadataReader(this.request()), table, element, language);
|
|
56
|
+
return { table, element, language, column: context.column, ...(context.set ? { choiceSet: choiceSet(context.set) } : {}),
|
|
57
|
+
choices: sorted(context.choices.map(toChoice)) };
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (isPolicyRefusal(error) || error instanceof MetadataScopeError)
|
|
61
|
+
throw stripSecretsFromError(error);
|
|
62
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Add the choice `options.value` (with `options.label`), or change the label, sequence, inactive flag or hint of the
|
|
67
|
+
* existing choice with that value. Reordering is a sequence change; inactivating keeps the choice for records that hold it.
|
|
68
|
+
*/
|
|
69
|
+
async setChoice(table, element, options) {
|
|
70
|
+
return this.write(table, element, options, false);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Remove the choice `options.value`. Refused while records hold the value unless `options.confirmInUse` is set; the
|
|
74
|
+
* records keep the value either way.
|
|
75
|
+
*/
|
|
76
|
+
async removeChoice(table, element, options) {
|
|
77
|
+
return this.write(table, element, options, true);
|
|
78
|
+
}
|
|
79
|
+
request() {
|
|
80
|
+
return SessionManager.getInstance().getRequest(this._instance);
|
|
81
|
+
}
|
|
82
|
+
async context(reader, table, element, language) {
|
|
83
|
+
const hierarchy = await ancestry(reader, table);
|
|
84
|
+
const definitions = await reader.rows('sys_dictionary', `nameIN${hierarchy.map(row => row.name).join(',')}^element=${element}`, 'sys_id,name,element,internal_type,choice,max_length,sys_scope');
|
|
85
|
+
// The nearest definition is the one that applies to the table.
|
|
86
|
+
const definition = hierarchy.map(row => definitions.find(entry => entry.name === row.name && entry.element === element)).find(Boolean);
|
|
87
|
+
if (!definition)
|
|
88
|
+
throw new MetadataScopeError('column_not_found', { table, field: element });
|
|
89
|
+
const sets = await reader.rows('sys_choice_set', `name=${table}^element=${element}`, 'sys_id,name,element,sys_scope,sys_update_name,sys_policy');
|
|
90
|
+
if (sets.length > 1 || sets.some(set => set.name !== table || set.element !== element))
|
|
91
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
92
|
+
const choices = await reader.rows(CHOICE, `name=${table}^element=${element}^language=${language}`, CHOICE_FIELDS);
|
|
93
|
+
if (choices.some(row => row.name !== table || row.element !== element || row.language !== language))
|
|
94
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
95
|
+
return { column: { table: definition.name, type: definition.internal_type, choice: definition.choice, scope: definition.sys_scope },
|
|
96
|
+
maxLength: Number(definition.max_length), set: sets[0], choices };
|
|
97
|
+
}
|
|
98
|
+
async write(table, element, options, removing) {
|
|
99
|
+
const language = options?.language ?? 'en';
|
|
100
|
+
if (!NAME.test(table ?? '') || !NAME.test(element ?? '') || typeof language !== 'string' || !LANGUAGE.test(language) ||
|
|
101
|
+
!options?.updateSet || !ID.test(options.updateSet))
|
|
102
|
+
throw new MetadataScopeError('invalid_input');
|
|
103
|
+
const { value } = options;
|
|
104
|
+
// The value is also a query term (the in-use count): no condition separator, no script, no padding.
|
|
105
|
+
if (typeof value !== 'string' || !value || value.length > 4000 || value !== value.trim() || CONTROL.test(value) || value.includes('^') ||
|
|
106
|
+
/javascript:/i.test(value))
|
|
107
|
+
throw new MetadataScopeError('invalid_input', { field: 'value' });
|
|
108
|
+
const changes = removing ? {} : changeFields(options);
|
|
109
|
+
const request = this.request();
|
|
110
|
+
const reader = new MetadataReader(request);
|
|
111
|
+
let submitted = false;
|
|
112
|
+
let recordId = '';
|
|
113
|
+
let report = {};
|
|
114
|
+
let messages = [];
|
|
115
|
+
try {
|
|
116
|
+
const { store, ...scope } = await resolveScope(reader, options.scope);
|
|
117
|
+
if (store && options.storeCustomization?.acknowledgeUpgradeSkip !== true)
|
|
118
|
+
throw new MetadataScopeError('store_scope');
|
|
119
|
+
const context = await this.context(reader, table, element, language);
|
|
120
|
+
if (context.set) {
|
|
121
|
+
if (context.set.sys_scope !== scope.sysId)
|
|
122
|
+
throw new MetadataScopeError('scope_mismatch', { table });
|
|
123
|
+
if (store && ['read', 'protected'].includes(context.set.sys_policy))
|
|
124
|
+
throw new MetadataScopeError('protected_record', { table });
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// A table without a list of its own shows the defining table's; a list of its own would replace it there.
|
|
128
|
+
if (context.column.table !== table)
|
|
129
|
+
throw new MetadataScopeError('choice_list_inherited', { table: context.column.table, field: element });
|
|
130
|
+
if (context.column.scope !== scope.sysId)
|
|
131
|
+
throw new MetadataScopeError('scope_mismatch', { table });
|
|
132
|
+
}
|
|
133
|
+
const matches = context.choices.filter(row => row.value === value);
|
|
134
|
+
if (matches.length > 1)
|
|
135
|
+
throw new MetadataScopeError('choice_ambiguous', { table, field: element });
|
|
136
|
+
const existing = matches[0];
|
|
137
|
+
const operation = removing ? 'delete' : existing ? 'update' : 'insert';
|
|
138
|
+
if (removing && !existing)
|
|
139
|
+
throw new MetadataScopeError('choice_not_found', { table, field: element });
|
|
140
|
+
let fields = {};
|
|
141
|
+
if (operation === 'insert') {
|
|
142
|
+
if (changes.label === undefined)
|
|
143
|
+
throw new MetadataScopeError('invalid_input', { field: 'label' });
|
|
144
|
+
// Records store the value in the column: it must fit it.
|
|
145
|
+
if (Number.isSafeInteger(context.maxLength) && context.maxLength > 0 && value.length > context.maxLength) {
|
|
146
|
+
throw new MetadataScopeError('invalid_input', { field: 'value' });
|
|
147
|
+
}
|
|
148
|
+
if (['integer', 'longint'].includes(context.column.type) && !/^-?\d+$/.test(value))
|
|
149
|
+
throw new MetadataScopeError('invalid_input', { field: 'value' });
|
|
150
|
+
fields = { value, ...changes };
|
|
151
|
+
}
|
|
152
|
+
else if (operation === 'update') {
|
|
153
|
+
fields = Object.fromEntries(Object.entries(changes).filter(([field, next]) => (existing[field] ?? '') !== next));
|
|
154
|
+
if (!Object.keys(fields).length)
|
|
155
|
+
throw new MetadataScopeError('choice_unchanged', { table, field: element });
|
|
156
|
+
}
|
|
157
|
+
const set = await reader.exact('sys_update_set', options.updateSet, 'application,state');
|
|
158
|
+
if (!set || set.state !== 'in progress' || set.application !== scope.sysId) {
|
|
159
|
+
throw new MetadataScopeError('invalid_input', set ? { updateSetState: set.state, updateSetApplication: set.application } : undefined);
|
|
160
|
+
}
|
|
161
|
+
let inUse;
|
|
162
|
+
if (operation === 'delete') {
|
|
163
|
+
inUse = await this.count(request, table, `${element}=${value}`);
|
|
164
|
+
if (inUse > 0 && options.confirmInUse !== true) {
|
|
165
|
+
throw new MetadataScopeError('choice_in_use', { table, field: element, records: inUse });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const users = await reader.rows('sys_user', 'sys_id=javascript:gs.getUserID()', 'sys_id');
|
|
169
|
+
if (users.length !== 1 || !ID.test(users[0].sys_id))
|
|
170
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
171
|
+
const user = users[0].sys_id;
|
|
172
|
+
const preferences = async () => {
|
|
173
|
+
const rows = await reader.rows('sys_user_preference', `user=${user}`, 'sys_id,user,name,value');
|
|
174
|
+
if (rows.some(pref => pref.user !== user))
|
|
175
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
176
|
+
return rows;
|
|
177
|
+
};
|
|
178
|
+
const before = await preferences();
|
|
179
|
+
const transport = createFormTransport(this._instance);
|
|
180
|
+
const form = await transport.loadForm(CHOICE, existing?.sys_id ?? '-1', {
|
|
181
|
+
...(operation === 'insert' ? { initialQuery: `name=${table}^element=${element}^language=${language}` } : {}),
|
|
182
|
+
query: { sysparm_transaction_scope: scope.sysId, sysparm_referring_url: `${CHOICE}.do`, sysparm_nofocus: 'true',
|
|
183
|
+
sysparm_nameofstack: `${randomUUID()}_bottomless` },
|
|
184
|
+
captureRenderedInputs: true, tokenSource: 'page', sensitive: true
|
|
185
|
+
});
|
|
186
|
+
recordId = form.sysId;
|
|
187
|
+
// Loaded in an application that may not use the table, the form drops the table and would save a choice without one.
|
|
188
|
+
if (!ID.test(recordId) || (existing && recordId !== existing.sys_id) || form.renderedInputs?.sysparm_transaction_scope !== scope.sysId ||
|
|
189
|
+
form.fields[`${CHOICE}.name`]?.value !== table || form.fields[`${CHOICE}.element`]?.value !== element ||
|
|
190
|
+
form.fields[`${CHOICE}.language`]?.value !== language)
|
|
191
|
+
throw new MetadataScopeError('scope_not_applied', { table });
|
|
192
|
+
for (const field of Object.keys(fields))
|
|
193
|
+
if (!form.fields[`${CHOICE}.${field}`])
|
|
194
|
+
throw new MetadataScopeError('field_not_supported', { field, table: CHOICE });
|
|
195
|
+
const action = operation === 'insert' ? 'sysverb_insert_and_stay' : operation === 'update' ? 'sysverb_update' : 'sysverb_delete';
|
|
196
|
+
if (operation === 'update' && !form.actions[action])
|
|
197
|
+
throw new MetadataScopeError('not_permitted');
|
|
198
|
+
if (operation === 'delete')
|
|
199
|
+
await requirePlatformDelete(reader, form.actions);
|
|
200
|
+
try {
|
|
201
|
+
transport.validate(form, { fields });
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
if (!(error instanceof InvalidParameterException))
|
|
205
|
+
throw error;
|
|
206
|
+
throw new MetadataScopeError('field_not_supported', { table: CHOICE });
|
|
207
|
+
}
|
|
208
|
+
const loaded = await preferences();
|
|
209
|
+
if (!comparePreferences(before, loaded).valid)
|
|
210
|
+
throw new MetadataVerificationError('session_changed', CHOICE, recordId, undefined, [], false);
|
|
211
|
+
const updateName = `sys_choice_${table}_${element}`;
|
|
212
|
+
const prior = await reader.rows('sys_update_xml', `name=${updateName}`, 'sys_id,name,sys_mod_count');
|
|
213
|
+
if (prior.some(row => row.name !== updateName || !/^\d+$/.test(row.sys_mod_count)))
|
|
214
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
215
|
+
const versions = new Map(prior.map(row => [row.sys_id, row.sys_mod_count]));
|
|
216
|
+
if (operation === 'delete') {
|
|
217
|
+
// Counted again just before the post: a record that took the value while the form loaded counts too.
|
|
218
|
+
inUse = await this.count(request, table, `${element}=${value}`);
|
|
219
|
+
if (inUse > 0 && options.confirmInUse !== true) {
|
|
220
|
+
throw new MetadataScopeError('choice_in_use', { table, field: element, records: inUse });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const started = new Date().toISOString().slice(0, 19).replace('T', ' ');
|
|
224
|
+
submitted = true;
|
|
225
|
+
let submitFailure;
|
|
226
|
+
try {
|
|
227
|
+
const result = await transport.submit(form, action, { fields, postAllRenderedInputs: true, tokenSource: 'page',
|
|
228
|
+
actionValue: operation === 'update' ? form.actions[action] : action,
|
|
229
|
+
extraFields: { sysparm_transaction_scope: scope.sysId, sysparm_transaction_update_set: options.updateSet,
|
|
230
|
+
sysparm_record_scope: '', sysparm_goto_url: '' },
|
|
231
|
+
redirect: 'manual', landing: 'guarded', sensitive: true });
|
|
232
|
+
messages = [...result.messages, ...(result.errors ?? [])];
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (isPolicyRefusal(error))
|
|
236
|
+
throw error;
|
|
237
|
+
if (error instanceof FormSubmitError)
|
|
238
|
+
messages = error.messages;
|
|
239
|
+
submitFailure = error;
|
|
240
|
+
}
|
|
241
|
+
report = { predictedUpdateSetSysId: options.updateSet, updateName };
|
|
242
|
+
const fail = code => {
|
|
243
|
+
throw new MetadataVerificationError(code, CHOICE, recordId, report, messages);
|
|
244
|
+
};
|
|
245
|
+
const csrfRejected = submitFailure instanceof Error && submitFailure.message === 'csrf_rejected';
|
|
246
|
+
const row = await reader.exact(CHOICE, recordId, CHOICE_FIELDS.slice('sys_id,'.length));
|
|
247
|
+
if (operation === 'delete') {
|
|
248
|
+
if (row)
|
|
249
|
+
fail(csrfRejected ? 'csrf_rejected' : 'delete_not_applied');
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
if (!row)
|
|
253
|
+
fail(csrfRejected ? 'csrf_rejected' : 'write_not_applied');
|
|
254
|
+
if (row.name !== table || row.element !== element || row.language !== language || row.value !== value ||
|
|
255
|
+
Object.entries(fields).some(([field, next]) => (row[field] ?? '') !== next))
|
|
256
|
+
fail('write_not_applied');
|
|
257
|
+
// Only the submitted form's row is this save's choice: another row of that value was written by someone else.
|
|
258
|
+
const same = await reader.rows(CHOICE, `name=${table}^element=${element}^language=${language}`, 'sys_id,value');
|
|
259
|
+
if (same.some(other => other.value === value && other.sys_id !== recordId))
|
|
260
|
+
fail('verification_unavailable');
|
|
261
|
+
}
|
|
262
|
+
// Every language: the capture holds the whole list.
|
|
263
|
+
const remaining = await reader.rows(CHOICE, `name=${table}^element=${element}`, CHOICE_FIELDS);
|
|
264
|
+
if (remaining.some(other => other.name !== table || other.element !== element))
|
|
265
|
+
fail('verification_unavailable');
|
|
266
|
+
const sets = await reader.rows('sys_choice_set', `name=${table}^element=${element}`, 'sys_id,name,element,sys_scope,sys_update_name');
|
|
267
|
+
if (sets.length > 1)
|
|
268
|
+
fail('verification_unavailable');
|
|
269
|
+
const savedSet = sets[0];
|
|
270
|
+
if (savedSet || remaining.length) {
|
|
271
|
+
if (!savedSet)
|
|
272
|
+
fail('not_captured');
|
|
273
|
+
report.recordScope = savedSet.sys_scope;
|
|
274
|
+
if (savedSet.sys_scope !== scope.sysId)
|
|
275
|
+
fail('scope_not_applied');
|
|
276
|
+
if (savedSet.sys_update_name !== updateName)
|
|
277
|
+
fail('not_captured');
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
report.recordScope = scope.sysId;
|
|
281
|
+
}
|
|
282
|
+
const observed = await reader.rows('sys_update_xml', `name=${updateName}^sys_updated_on>=${started}`, 'sys_id,name,update_set,application,action,sys_updated_on,sys_mod_count');
|
|
283
|
+
const comparison = comparePreferences(before, await preferences(), options.updateSet);
|
|
284
|
+
Object.assign(report, { preferencesUnchanged: comparison.unchanged, preferenceRowsReplaced: comparison.replaced, currentUpdateSet: comparison.currentUpdateSet });
|
|
285
|
+
if (observed.some(capture => capture.name !== updateName || capture.sys_updated_on < started))
|
|
286
|
+
fail('not_captured');
|
|
287
|
+
const changed = observed.filter(capture => versions.get(capture.sys_id) !== capture.sys_mod_count);
|
|
288
|
+
if (!changed.length)
|
|
289
|
+
fail('not_captured');
|
|
290
|
+
// One save rewrites one capture of the list; more than one changed row cannot be attributed to it.
|
|
291
|
+
if (changed.length > 1)
|
|
292
|
+
fail('verification_unavailable');
|
|
293
|
+
const capture = changed[0];
|
|
294
|
+
const target = ID.test(capture.update_set) ? await reader.exact('sys_update_set', capture.update_set, 'name,application') : undefined;
|
|
295
|
+
if (!target)
|
|
296
|
+
fail('not_captured');
|
|
297
|
+
Object.assign(report, { updateSetSysId: target.sys_id, updateSetName: target.name, updateSetScope: target.application, action: capture.action });
|
|
298
|
+
if (target.sys_id !== options.updateSet)
|
|
299
|
+
fail('captured_elsewhere');
|
|
300
|
+
if (target.application !== scope.sysId || capture.application !== scope.sysId)
|
|
301
|
+
fail('mixed_scope_capture');
|
|
302
|
+
// Emptying a list keeps its choice set, and the capture holds it with no choices; only a list with no choice set left is a DELETE.
|
|
303
|
+
const emptied = !savedSet && !remaining.length;
|
|
304
|
+
if (capture.action !== (emptied ? 'DELETE' : 'INSERT_OR_UPDATE'))
|
|
305
|
+
fail('not_captured');
|
|
306
|
+
if (!emptied) {
|
|
307
|
+
// A commit replaces the target's list with the capture's, so the capture must be the list as it now is: every
|
|
308
|
+
// choice, in every language, with every field a commit applies. That holds this save's choice as saved, and no
|
|
309
|
+
// longer holds a removed one.
|
|
310
|
+
const payload = await reader.exact('sys_update_xml', capture.sys_id, 'payload');
|
|
311
|
+
const captured = payload ? await capturedChoices(payload.payload) : undefined;
|
|
312
|
+
if (!captured)
|
|
313
|
+
fail('verification_unavailable');
|
|
314
|
+
if (captured.size !== remaining.length || remaining.some(saved => {
|
|
315
|
+
const entry = captured.get(saved.sys_id);
|
|
316
|
+
return !entry || CAPTURED_FIELDS.some(field => entry[field] !== (saved[field] ?? ''));
|
|
317
|
+
}))
|
|
318
|
+
fail('not_captured');
|
|
319
|
+
}
|
|
320
|
+
if (store)
|
|
321
|
+
report.customization = await customizationEvidence(reader, capture.sys_id, updateName);
|
|
322
|
+
if (!comparison.valid)
|
|
323
|
+
fail('session_changed');
|
|
324
|
+
if (submitFailure)
|
|
325
|
+
fail(csrfRejected ? 'csrf_rejected' : 'verification_unavailable');
|
|
326
|
+
const after = await reader.rows(CHOICE, `name=${table}^element=${element}^language=${language}`, CHOICE_FIELDS);
|
|
327
|
+
return { table, element, language, value, action: operation, sysId: recordId,
|
|
328
|
+
...(row ? { choice: toChoice(row) } : {}), ...(existing ? { previous: toChoice(existing) } : {}),
|
|
329
|
+
choices: sorted(after.map(toChoice)), column: context.column,
|
|
330
|
+
...(savedSet ? { choiceSet: { ...choiceSet(savedSet), created: !context.set } } : {}),
|
|
331
|
+
...(inUse !== undefined ? { inUse } : {}), scope, capture: report, messages };
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
if (isPolicyRefusal(error) || (!submitted && error instanceof MetadataScopeError) || error instanceof MetadataVerificationError)
|
|
335
|
+
throw stripSecretsFromError(error);
|
|
336
|
+
if (!submitted && error instanceof Error && error.message === 'csrf_token_unavailable')
|
|
337
|
+
throw new MetadataScopeError('csrf_token_unavailable');
|
|
338
|
+
if (!submitted && error instanceof Error && error.message === 'form_redirect') {
|
|
339
|
+
throw new MetadataScopeError('form_redirected', { table: CHOICE, redirectPath: error.redirectPath });
|
|
340
|
+
}
|
|
341
|
+
if (!submitted)
|
|
342
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
343
|
+
throw new MetadataVerificationError(error instanceof Error && error.message === 'csrf_rejected' ? 'csrf_rejected' : 'verification_unavailable', CHOICE, recordId, report, messages);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/** Records holding a value, from the Stats API: a paged read is bounded, a count is not. */
|
|
347
|
+
async count(request, table, query) {
|
|
348
|
+
const response = await request.get({ path: `/api/now/stats/${table}`,
|
|
349
|
+
headers: { Accept: 'application/json' }, body: null, requires: READ_ONLY, sensitive: true, query: { sysparm_query: query, sysparm_count: 'true' } });
|
|
350
|
+
const count = Number(response.bodyObject?.result?.stats?.count);
|
|
351
|
+
if (response.status !== 200 || !Number.isSafeInteger(count) || count < 0)
|
|
352
|
+
throw new MetadataScopeError('evidence_unavailable');
|
|
353
|
+
return count;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/** The fields a set writes, as the form posts them; refuses values the platform would not keep as given. */
|
|
357
|
+
function changeFields(options) {
|
|
358
|
+
const { label, sequence, inactive, hint } = options;
|
|
359
|
+
const fields = {};
|
|
360
|
+
if (label !== undefined) {
|
|
361
|
+
if (typeof label !== 'string' || !label.trim() || label !== label.trim() || label.length > 100 || CONTROL.test(label)) {
|
|
362
|
+
throw new MetadataScopeError('invalid_input', { field: 'label' });
|
|
363
|
+
}
|
|
364
|
+
fields.label = label;
|
|
365
|
+
}
|
|
366
|
+
if (sequence !== undefined) {
|
|
367
|
+
if (!Number.isSafeInteger(sequence) || Math.abs(sequence) > MAX_SEQUENCE)
|
|
368
|
+
throw new MetadataScopeError('invalid_input', { field: 'sequence' });
|
|
369
|
+
fields.sequence = String(sequence);
|
|
370
|
+
}
|
|
371
|
+
if (inactive !== undefined) {
|
|
372
|
+
if (typeof inactive !== 'boolean')
|
|
373
|
+
throw new MetadataScopeError('invalid_input', { field: 'inactive' });
|
|
374
|
+
fields.inactive = String(inactive);
|
|
375
|
+
}
|
|
376
|
+
if (hint !== undefined) {
|
|
377
|
+
if (typeof hint !== 'string' || hint.length > 255 || hint !== hint.trim() || CONTROL.test(hint))
|
|
378
|
+
throw new MetadataScopeError('invalid_input', { field: 'hint' });
|
|
379
|
+
fields.hint = hint;
|
|
380
|
+
}
|
|
381
|
+
return fields;
|
|
382
|
+
}
|
|
383
|
+
function toChoice(row) {
|
|
384
|
+
const sequence = /^-?\d+$/.test(row.sequence ?? '') ? Number(row.sequence) : undefined;
|
|
385
|
+
return { sysId: row.sys_id, value: row.value, label: row.label, ...(sequence !== undefined ? { sequence } : {}),
|
|
386
|
+
inactive: row.inactive === 'true', hint: row.hint ?? '', dependentValue: row.dependent_value ?? '', language: row.language };
|
|
387
|
+
}
|
|
388
|
+
function sorted(choices) {
|
|
389
|
+
const order = (choice) => choice.sequence ?? Number.MAX_SAFE_INTEGER;
|
|
390
|
+
return [...choices].sort((a, b) => order(a) - order(b) || (a.value < b.value ? -1 : a.value > b.value ? 1 : 0));
|
|
391
|
+
}
|
|
392
|
+
function choiceSet(row) {
|
|
393
|
+
return { sysId: row.sys_id, scope: row.sys_scope, updateName: row.sys_update_name };
|
|
394
|
+
}
|
|
395
|
+
/** The choices a Choice list capture holds, by sys_id; undefined when the payload is not one. */
|
|
396
|
+
async function capturedChoices(payload) {
|
|
397
|
+
let document;
|
|
398
|
+
// xml2js ships no types that the type-aware lint can resolve (as in XMLRecordManager).
|
|
399
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
400
|
+
try {
|
|
401
|
+
document = await new Parser({ explicitArray: true }).parseStringPromise(payload);
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
return undefined;
|
|
405
|
+
}
|
|
406
|
+
const list = document?.record_update?.sys_choice;
|
|
407
|
+
if (!Array.isArray(list) || list.length !== 1)
|
|
408
|
+
return undefined;
|
|
409
|
+
const rows = list[0].sys_choice ?? [];
|
|
410
|
+
const result = new Map();
|
|
411
|
+
for (const entry of rows) {
|
|
412
|
+
const record = entry;
|
|
413
|
+
const sysId = text(record.sys_id);
|
|
414
|
+
if (!sysId || result.has(sysId))
|
|
415
|
+
return undefined;
|
|
416
|
+
const fields = Object.fromEntries(CAPTURED_FIELDS.map(field => [field, text(record[field])]));
|
|
417
|
+
// A field missing from the capture is not the same as an empty one.
|
|
418
|
+
if (Object.values(fields).some(field => field === undefined))
|
|
419
|
+
return undefined;
|
|
420
|
+
result.set(sysId, fields);
|
|
421
|
+
}
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
/** xml2js gives `['text']`, `[{ _: 'text', $: {...} }]` or `['']`/`[{ $: {...} }]` for an empty element. */
|
|
425
|
+
function text(node) {
|
|
426
|
+
if (!Array.isArray(node) || node.length !== 1)
|
|
427
|
+
return undefined;
|
|
428
|
+
const first = node[0];
|
|
429
|
+
if (typeof first === 'string')
|
|
430
|
+
return first;
|
|
431
|
+
if (first && typeof first === 'object')
|
|
432
|
+
return typeof first._ === 'string' ? first._ : '';
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=ChoiceWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChoiceWriter.js","sourceRoot":"","sources":["../../../src/sn/metadata/ChoiceWriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,18 +10,12 @@ import { MetadataVerificationError } from './MetadataVerificationError.js';
|
|
|
10
10
|
import { MetadataReader } from './internal/MetadataReader.js';
|
|
11
11
|
import { comparePreferences, preferenceValue } from './internal/MetadataPreferences.js';
|
|
12
12
|
import { customizationEvidence, resolveScope } from './internal/MetadataScope.js';
|
|
13
|
+
import { ancestry } from './internal/MetadataTables.js';
|
|
13
14
|
const ID = /^[a-f0-9]{32}$/i;
|
|
14
15
|
const NAME = /^[a-z0-9_]+$/i;
|
|
15
16
|
const COLUMN = /^[a-z][a-z0-9_]*$/;
|
|
16
17
|
const MAX_COLUMN = 80;
|
|
17
18
|
const DICTIONARY = 'sys_dictionary';
|
|
18
|
-
/**
|
|
19
|
-
* Tables whose schema the platform's own metadata, capture and application model depend on. A column added to one of
|
|
20
|
-
* them (or to a table extending one) is added to every record the platform keeps there.
|
|
21
|
-
*/
|
|
22
|
-
const TABLE_DENY = new Set(['sys_metadata', 'sys_dictionary', 'sys_db_object', 'sys_documentation', 'sys_choice', 'sys_glide_object',
|
|
23
|
-
'sys_update_set', 'sys_update_xml', 'sys_update_version', 'sys_metadata_delete', 'sys_scope', 'sys_app', 'sys_store_app',
|
|
24
|
-
'sys_user_preference']);
|
|
25
19
|
/**
|
|
26
20
|
* Adds a column to a table through the dictionary form (`sys_dictionary.do`), the path the platform itself uses, and
|
|
27
21
|
* verifies what the platform did:
|
|
@@ -266,27 +260,4 @@ function columnName(requested, scope, store, tableScope) {
|
|
|
266
260
|
const prefix = scope.sysId === 'global' || store ? 'u_' : tableScope === scope.sysId ? '' : `${scope.scope}_`;
|
|
267
261
|
return requested.startsWith(prefix) ? requested : `${prefix}${requested}`;
|
|
268
262
|
}
|
|
269
|
-
/** The table and every table it extends, the table first. Refuses the platform's own schema tables. */
|
|
270
|
-
async function ancestry(reader, table) {
|
|
271
|
-
const fields = 'sys_id,name,super_class,sys_scope';
|
|
272
|
-
let rows = await reader.rows('sys_db_object', `name=${table}`, fields);
|
|
273
|
-
if (rows.length !== 1 || rows[0].name !== table)
|
|
274
|
-
throw new MetadataScopeError('table_not_supported', { table });
|
|
275
|
-
const chain = [];
|
|
276
|
-
while (rows.length === 1) {
|
|
277
|
-
const row = rows[0];
|
|
278
|
-
if (chain.some(seen => seen.sys_id === row.sys_id) || chain.length > 30)
|
|
279
|
-
throw new MetadataScopeError('evidence_unavailable');
|
|
280
|
-
if (TABLE_DENY.has(row.name) || !NAME.test(row.name))
|
|
281
|
-
throw new MetadataScopeError('table_not_supported', { table: row.name });
|
|
282
|
-
chain.push(row);
|
|
283
|
-
if (!ID.test(row.super_class))
|
|
284
|
-
return chain;
|
|
285
|
-
const parent = await reader.exact('sys_db_object', row.super_class, 'name,super_class,sys_scope');
|
|
286
|
-
if (!parent)
|
|
287
|
-
throw new MetadataScopeError('evidence_unavailable');
|
|
288
|
-
rows = [parent];
|
|
289
|
-
}
|
|
290
|
-
throw new MetadataScopeError('evidence_unavailable');
|
|
291
|
-
}
|
|
292
263
|
//# sourceMappingURL=ColumnWriter.js.map
|