udp-stencil-component-library 26.8.0 → 26.9.0-beta.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/cjs/advanced-search_12.cjs.entry.js +3 -3
- package/dist/cjs/ag-grid-base_65.cjs.entry.js +4 -4
- package/dist/cjs/ambient-template-grid.cjs.entry.js +3 -3
- package/dist/cjs/api-method-instance-grid.cjs.entry.js +5 -5
- package/dist/cjs/{apiMethodInstance-Dl1OvqO3.js → apiMethodInstance-D65NIw8S.js} +1 -1
- package/dist/cjs/{apiUtils-DMOOqk3y.js → apiUtils-0pkNuvqf.js} +412 -18
- package/dist/cjs/{catalog-store-CrTx8FL-.js → catalog-store-B_YMkXRh.js} +1 -1
- package/dist/cjs/{configureUdpColumnMods-CongQl55.js → configureUdpColumnMods-BT7UbQPh.js} +1 -1
- package/dist/cjs/index.cjs.js +27 -6
- package/dist/cjs/{lookupHelper-DPnaYUT4.js → lookupHelper-ClpMWN_g.js} +1 -1
- package/dist/cjs/search-method-grid.cjs.entry.js +13 -7
- package/dist/collection/components/grid/new-grid/datasources/searchMethodDatasource.js +9 -3
- package/dist/collection/components/grid/new-grid/search-method-grid.js +5 -4
- package/dist/collection/index.js +1 -0
- package/dist/collection/store/execution-store.js +332 -0
- package/dist/collection/udp-utilities/api-udp/apiUtils.js +54 -16
- package/dist/components/ag-grid-base2.js +1 -1
- package/dist/components/ambient-template-grid.js +1 -1
- package/dist/components/apiUtils.js +1 -1
- package/dist/components/catalog-store.js +1 -1
- package/dist/components/configureUdpColumnMods.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/search-method-grid2.js +1 -1
- package/dist/components/udp-export-sheet2.js +1 -1
- package/dist/docs.json +5 -5
- package/dist/esm/advanced-search_12.entry.js +3 -3
- package/dist/esm/ag-grid-base_65.entry.js +4 -4
- package/dist/esm/ambient-template-grid.entry.js +3 -3
- package/dist/esm/api-method-instance-grid.entry.js +5 -5
- package/dist/esm/{apiMethodInstance-V3OfLZqE.js → apiMethodInstance-BunReWfq.js} +1 -1
- package/dist/esm/{apiUtils-5ytQ3Uwx.js → apiUtils-Cq-WuEqc.js} +390 -18
- package/dist/esm/{catalog-store-C3AM0WtT.js → catalog-store-CLsDGUEl.js} +1 -1
- package/dist/esm/{configureUdpColumnMods-Bob9zsKz.js → configureUdpColumnMods-UWccWlH6.js} +1 -1
- package/dist/esm/index.js +6 -6
- package/dist/esm/{lookupHelper-B7F-SThL.js → lookupHelper-CSo9DNLr.js} +1 -1
- package/dist/esm/search-method-grid.entry.js +13 -7
- package/dist/stencil-library/advanced-search_12.entry.js +1 -1
- package/dist/stencil-library/ag-grid-base_65.entry.js +1 -1
- package/dist/stencil-library/ambient-template-grid.entry.js +1 -1
- package/dist/stencil-library/api-method-instance-grid.entry.js +1 -1
- package/dist/stencil-library/{apiMethodInstance-V3OfLZqE.js → apiMethodInstance-BunReWfq.js} +1 -1
- package/dist/stencil-library/apiUtils-Cq-WuEqc.js +1 -0
- package/dist/stencil-library/{catalog-store-C3AM0WtT.js → catalog-store-CLsDGUEl.js} +1 -1
- package/dist/stencil-library/{configureUdpColumnMods-Bob9zsKz.js → configureUdpColumnMods-UWccWlH6.js} +1 -1
- package/dist/stencil-library/index.esm.js +1 -1
- package/dist/stencil-library/lookupHelper-CSo9DNLr.js +1 -0
- package/dist/stencil-library/search-method-grid.entry.js +1 -1
- package/dist/types/components/grid/new-grid/datasources/searchMethodDatasource.d.ts +1 -0
- package/dist/types/components/grid/new-grid/search-method-grid.d.ts +6 -0
- package/dist/types/components.d.ts +12 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/store/execution-store.d.ts +181 -0
- package/dist/types/udp-utilities/api-udp/apiUtils.d.ts +8 -0
- package/package.json +1 -1
- package/dist/stencil-library/apiUtils-5ytQ3Uwx.js +0 -1
- package/dist/stencil-library/lookupHelper-B7F-SThL.js +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./index-CZB9dMeB.js');
|
|
4
4
|
var conversionFunctions = require('./conversionFunctions-B_9y17KE.js');
|
|
5
|
-
var catalogStore = require('./catalog-store-
|
|
5
|
+
var catalogStore = require('./catalog-store-B_YMkXRh.js');
|
|
6
6
|
var Close24 = require('@carbon/icons/es/close/24');
|
|
7
7
|
var uuid = require('uuid');
|
|
8
8
|
var Save16 = require('@carbon/icons/es/save/16');
|
|
@@ -14,8 +14,8 @@ var Star16 = require('@carbon/icons/es/star/16');
|
|
|
14
14
|
var AdvancedQuery16 = require('@carbon/icons/es/ibm-watson--discovery/16');
|
|
15
15
|
var DataEnrichment16 = require('@carbon/icons/es/idea/16');
|
|
16
16
|
var Renew16 = require('@carbon/icons/es/renew/16');
|
|
17
|
-
require('./apiUtils-
|
|
18
|
-
require('
|
|
17
|
+
require('./apiUtils-0pkNuvqf.js');
|
|
18
|
+
require('lodash-es/isEqual');
|
|
19
19
|
require('./makeApiCall-CFfg9gI0.js');
|
|
20
20
|
require('axios');
|
|
21
21
|
require('./configService-N6ke1_s4.js');
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./index-CZB9dMeB.js');
|
|
4
4
|
var agGridEnterpriseV33 = require('ag-grid-enterprise-v33');
|
|
5
|
-
var apiUtils = require('./apiUtils-
|
|
6
|
-
var lookupHelper = require('./lookupHelper-
|
|
5
|
+
var apiUtils = require('./apiUtils-0pkNuvqf.js');
|
|
6
|
+
var lookupHelper = require('./lookupHelper-ClpMWN_g.js');
|
|
7
7
|
var tenantUtils = require('./tenantUtils-BCKSE0vq.js');
|
|
8
8
|
var searchObject = require('./searchObject-mbqgqdRh.js');
|
|
9
9
|
var searchObjectHelper = require('./searchObjectHelper-DYpPEIzz.js');
|
|
10
10
|
var statusRenderer = require('./status-renderer-9CQ-hhq8.js');
|
|
11
|
-
var configureUdpColumnMods = require('./configureUdpColumnMods-
|
|
11
|
+
var configureUdpColumnMods = require('./configureUdpColumnMods-BT7UbQPh.js');
|
|
12
12
|
var lodashEs = require('lodash-es');
|
|
13
13
|
var makeApiCall = require('./makeApiCall-CFfg9gI0.js');
|
|
14
14
|
var configService = require('./configService-N6ke1_s4.js');
|
|
@@ -58,7 +58,7 @@ require('@fluentui/web-components/textarea.js');
|
|
|
58
58
|
require('@fluentui/web-components/tooltip.js');
|
|
59
59
|
require('@fluentui/web-components/tree.js');
|
|
60
60
|
require('@fluentui/web-components/tree-item.js');
|
|
61
|
-
require('
|
|
61
|
+
require('lodash-es/isEqual');
|
|
62
62
|
require('axios');
|
|
63
63
|
require('./iconMapping-D932h4o2.js');
|
|
64
64
|
require('@carbon/icons/es/add/16');
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./index-CZB9dMeB.js');
|
|
4
4
|
var immer = require('immer');
|
|
5
|
-
var catalogStore = require('./catalog-store-
|
|
5
|
+
var catalogStore = require('./catalog-store-B_YMkXRh.js');
|
|
6
6
|
var ChooseItem16 = require('@carbon/icons/es/choose-item/16');
|
|
7
7
|
var Star16 = require('@carbon/icons/es/star/16');
|
|
8
8
|
var List16 = require('@carbon/icons/es/list/16');
|
|
9
|
-
var apiUtils = require('./apiUtils-
|
|
9
|
+
var apiUtils = require('./apiUtils-0pkNuvqf.js');
|
|
10
10
|
var transformSearchData = require('./transformSearchData-B4bk4Aik.js');
|
|
11
11
|
var conversionFunctions = require('./conversionFunctions-B_9y17KE.js');
|
|
12
12
|
var localforage = require('localforage');
|
|
@@ -16,7 +16,7 @@ var fastTypescriptMemoize = require('fast-typescript-memoize');
|
|
|
16
16
|
var lodashEs = require('lodash-es');
|
|
17
17
|
var uuid = require('uuid');
|
|
18
18
|
var tenantUtils = require('./tenantUtils-BCKSE0vq.js');
|
|
19
|
-
require('
|
|
19
|
+
require('lodash-es/isEqual');
|
|
20
20
|
require('./makeApiCall-CFfg9gI0.js');
|
|
21
21
|
require('axios');
|
|
22
22
|
require('./configService-N6ke1_s4.js');
|
|
@@ -4,14 +4,14 @@ var index = require('./index-CZB9dMeB.js');
|
|
|
4
4
|
var makeApiCall = require('./makeApiCall-CFfg9gI0.js');
|
|
5
5
|
var searchObjectHelper = require('./searchObjectHelper-DYpPEIzz.js');
|
|
6
6
|
var lodashEs = require('lodash-es');
|
|
7
|
-
var apiMethodInstance = require('./apiMethodInstance-
|
|
7
|
+
var apiMethodInstance = require('./apiMethodInstance-D65NIw8S.js');
|
|
8
8
|
var configService = require('./configService-N6ke1_s4.js');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('./searchObject-mbqgqdRh.js');
|
|
11
|
-
require('./configureUdpColumnMods-
|
|
12
|
-
require('./lookupHelper-
|
|
13
|
-
require('./apiUtils-
|
|
14
|
-
require('
|
|
11
|
+
require('./configureUdpColumnMods-BT7UbQPh.js');
|
|
12
|
+
require('./lookupHelper-ClpMWN_g.js');
|
|
13
|
+
require('./apiUtils-0pkNuvqf.js');
|
|
14
|
+
require('lodash-es/isEqual');
|
|
15
15
|
require('./tenantUtils-BCKSE0vq.js');
|
|
16
16
|
|
|
17
17
|
const ApiMethodInstanceGrid = class {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var configureUdpColumnMods = require('./configureUdpColumnMods-
|
|
3
|
+
var configureUdpColumnMods = require('./configureUdpColumnMods-BT7UbQPh.js');
|
|
4
4
|
|
|
5
5
|
function mapDotNetTypeToAgGridType(type) {
|
|
6
6
|
const normalized = type.replace(/\?$/, '').trim().toLowerCase();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var isEqual = require('lodash-es/isEqual');
|
|
4
4
|
var makeApiCall = require('./makeApiCall-CFfg9gI0.js');
|
|
5
5
|
var configService = require('./configService-N6ke1_s4.js');
|
|
6
6
|
var index = require('./index-CZB9dMeB.js');
|
|
@@ -8,7 +8,7 @@ var tenantUtils = require('./tenantUtils-BCKSE0vq.js');
|
|
|
8
8
|
|
|
9
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var isEqual__default = /*#__PURE__*/_interopDefault(isEqual);
|
|
12
12
|
|
|
13
13
|
const appendToMap = (map, propName, value) => {
|
|
14
14
|
const items = map.get(propName);
|
|
@@ -238,15 +238,15 @@ const getBaseUrls = async () => {
|
|
|
238
238
|
return baseUrls;
|
|
239
239
|
};
|
|
240
240
|
|
|
241
|
-
const { state, onChange } = createStore({
|
|
241
|
+
const { state: state$1, onChange } = createStore({
|
|
242
242
|
lookupsDataMap: null,
|
|
243
243
|
});
|
|
244
244
|
function setLookupsDataMap(lookupsDataMap, replace = false) {
|
|
245
245
|
if (replace) {
|
|
246
|
-
state.lookupsDataMap = lookupsDataMap;
|
|
246
|
+
state$1.lookupsDataMap = lookupsDataMap;
|
|
247
247
|
}
|
|
248
248
|
else {
|
|
249
|
-
state.lookupsDataMap = Object.assign(Object.assign({}, state.lookupsDataMap), lookupsDataMap);
|
|
249
|
+
state$1.lookupsDataMap = Object.assign(Object.assign({}, state$1.lookupsDataMap), lookupsDataMap);
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -254,9 +254,342 @@ var lookupsStore = /*#__PURE__*/Object.freeze({
|
|
|
254
254
|
__proto__: null,
|
|
255
255
|
onChange: onChange,
|
|
256
256
|
setLookupsDataMap: setLookupsDataMap,
|
|
257
|
-
state: state
|
|
257
|
+
state: state$1
|
|
258
258
|
});
|
|
259
259
|
|
|
260
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
261
|
+
/**
|
|
262
|
+
* BasicOperation type ids of the promoted base operations executable
|
|
263
|
+
* product-side — every operation the emitted UdpQuery runtime dispatches
|
|
264
|
+
* (UNT-6403): reads (Get=1, GetAll=5, Search=6, GetConfig=7, GetFull=8,
|
|
265
|
+
* Describe=9, GetData=10, Export=16, GetFileResult=18), writes (Create=2,
|
|
266
|
+
* Update=3, Delete=4, Import=15), and the virtual row operations
|
|
267
|
+
* (VirtualGet..VirtualDelete=11-14). BulkCreate=17 is dispatcher-ready but
|
|
268
|
+
* excluded until PromotedApiMethodView gains a BulkCreate slot the catalog can
|
|
269
|
+
* expose. The dispatcher independently rejects anything it does not support
|
|
270
|
+
* (501), so this list is a routing optimization, not a security boundary.
|
|
271
|
+
*/
|
|
272
|
+
const DIRECT_ELIGIBLE_BASE_OPERATION_TYPE_IDS = [
|
|
273
|
+
'1',
|
|
274
|
+
'2',
|
|
275
|
+
'3',
|
|
276
|
+
'4',
|
|
277
|
+
'5',
|
|
278
|
+
'6',
|
|
279
|
+
'7',
|
|
280
|
+
'8',
|
|
281
|
+
'9',
|
|
282
|
+
'10',
|
|
283
|
+
'11',
|
|
284
|
+
'12',
|
|
285
|
+
'13',
|
|
286
|
+
'14',
|
|
287
|
+
'15',
|
|
288
|
+
'16',
|
|
289
|
+
'18',
|
|
290
|
+
];
|
|
291
|
+
// The stencil dist ships several bundle flavors, and a page routinely loads two of
|
|
292
|
+
// them at once: utility imports through the package root resolve to dist/esm, while
|
|
293
|
+
// the React wrappers load the components (and everything they bundle, including this
|
|
294
|
+
// module) from dist/components. Module-scoped state therefore SPLITS — the enterprise
|
|
295
|
+
// library's writes land in the esm copy while the grid datasource reads the
|
|
296
|
+
// components copy. Backing the state with a namespaced global keeps every compiled
|
|
297
|
+
// copy reading and writing the same object. Reads are imperative (resolveExecutionTarget
|
|
298
|
+
// at request time), so no store reactivity is needed.
|
|
299
|
+
const EXECUTION_STATE_GLOBAL_KEY = '__udpQueryExecutionState__';
|
|
300
|
+
const globalScope = globalThis;
|
|
301
|
+
const state = ((_a = globalScope[EXECUTION_STATE_GLOBAL_KEY]) !== null && _a !== void 0 ? _a : (globalScope[EXECUTION_STATE_GLOBAL_KEY] = {
|
|
302
|
+
queryExecution: null,
|
|
303
|
+
directEligibleApiMethodIds: [],
|
|
304
|
+
integrationOnlyIds: [],
|
|
305
|
+
integrationFallbackStatuses: {},
|
|
306
|
+
descriptorKnown: false,
|
|
307
|
+
eligibilityKnown: false,
|
|
308
|
+
descriptorResolving: false,
|
|
309
|
+
descriptorWaiters: [],
|
|
310
|
+
}));
|
|
311
|
+
// A copy of this module compiled into an older bundle may have created the
|
|
312
|
+
// global without newer fields; heal the shape instead of trusting it.
|
|
313
|
+
(_b = state.integrationOnlyIds) !== null && _b !== void 0 ? _b : (state.integrationOnlyIds = []);
|
|
314
|
+
(_c = state.integrationFallbackStatuses) !== null && _c !== void 0 ? _c : (state.integrationFallbackStatuses = {});
|
|
315
|
+
(_d = state.descriptorKnown) !== null && _d !== void 0 ? _d : (state.descriptorKnown = false);
|
|
316
|
+
(_e = state.eligibilityKnown) !== null && _e !== void 0 ? _e : (state.eligibilityKnown = false);
|
|
317
|
+
(_f = state.descriptorResolving) !== null && _f !== void 0 ? _f : (state.descriptorResolving = false);
|
|
318
|
+
(_g = state.descriptorWaiters) !== null && _g !== void 0 ? _g : (state.descriptorWaiters = []);
|
|
319
|
+
/**
|
|
320
|
+
* Strips trailing '/' characters. A loop rather than `/\/+$/`, which
|
|
321
|
+
* backtracks quadratically on inputs with many embedded slashes.
|
|
322
|
+
*/
|
|
323
|
+
const trimTrailingSlashes = (url) => {
|
|
324
|
+
let end = url.length;
|
|
325
|
+
while (end > 0 && url[end - 1] === '/')
|
|
326
|
+
end--;
|
|
327
|
+
return url.slice(0, end);
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* Ad hoc UdpQuery execution endpoint emitted into every generated product app —
|
|
331
|
+
* contract with the code generator's UdpQueryControllerGenerator.
|
|
332
|
+
*/
|
|
333
|
+
const buildDirectAdhocRequestUrl = (productBaseUrl, apiMethodId) => `${trimTrailingSlashes(productBaseUrl)}/api/v1/UdpQuery/adhoc/${apiMethodId}`;
|
|
334
|
+
/**
|
|
335
|
+
* With-parameters UdpQuery execution endpoint emitted into every generated
|
|
336
|
+
* product app — the direct counterpart of Integration's
|
|
337
|
+
* `apimethod/executeQueryWithParameters/{apiMethodId}`. Same request body
|
|
338
|
+
* contract (a flat name→value map plus an optional `requestBody` entry).
|
|
339
|
+
*/
|
|
340
|
+
const buildDirectExecuteWithParametersUrl = (productBaseUrl, apiMethodId) => `${trimTrailingSlashes(productBaseUrl)}/api/v1/UdpQuery/${apiMethodId}/executeWithParameters`;
|
|
341
|
+
/**
|
|
342
|
+
* Instance-mode UdpQuery execution endpoint (saved query instances, the only
|
|
343
|
+
* mode applying alias/lookup result mapping). Per-instance operation
|
|
344
|
+
* eligibility cannot be derived client-side — the promoted catalog keys by
|
|
345
|
+
* apiMethodId, not instance id — so instance callers route direct on the
|
|
346
|
+
* descriptor alone and rely on the dispatcher's 501 plus the fallback contract.
|
|
347
|
+
*/
|
|
348
|
+
const buildDirectExecuteInstanceUrl = (productBaseUrl, apiMethodInstanceId) => `${trimTrailingSlashes(productBaseUrl)}/api/v1/UdpQuery/${apiMethodInstanceId}/execute`;
|
|
349
|
+
/**
|
|
350
|
+
* Response header the emitted UdpQuery controller stamps on every response it
|
|
351
|
+
* produces, success and error alike. Its absence on a 404 means the endpoint
|
|
352
|
+
* itself is missing (a build without the runtime); the product's CORS policy
|
|
353
|
+
* must expose it (Access-Control-Expose-Headers) for cross-origin callers.
|
|
354
|
+
*/
|
|
355
|
+
const UDP_QUERY_RUNTIME_MARKER_HEADER = 'x-udpquery-runtime';
|
|
356
|
+
/**
|
|
357
|
+
* The migration-window fallback contract for a failed DIRECT execution: retry
|
|
358
|
+
* via Integration only on 501 (the runtime's "not supported / not configured
|
|
359
|
+
* here — execute on Integration" signal, which also covers product builds
|
|
360
|
+
* whose runtime predates an operation), on a 404 WITHOUT the runtime marker
|
|
361
|
+
* header (endpoint absent), and — for reads only — on 503. Never on
|
|
362
|
+
* marker-carrying 404s or any other status — a real query error must surface,
|
|
363
|
+
* not silently re-execute on the other path and mask a broken direct route.
|
|
364
|
+
*/
|
|
365
|
+
const shouldFallBackToIntegration = (status, hasRuntimeMarker, options = {}) => status === 501 || (status === 503 && !options.mayWrite) || (status === 404 && !hasRuntimeMarker);
|
|
366
|
+
/**
|
|
367
|
+
* The one implementation of the migration-window fallback, shared by every
|
|
368
|
+
* executor seam (stencil apiUtils, the React library's methodUtils): run the
|
|
369
|
+
* direct call, and on a {@link shouldFallBackToIntegration} failure retry via
|
|
370
|
+
* Integration; rethrow everything else. 501 and markerless 404 describe the
|
|
371
|
+
* deployed build, so the id goes integration-only for the rest of the page
|
|
372
|
+
* load; 503 is transient, so only this call falls back.
|
|
373
|
+
*/
|
|
374
|
+
const directCallWithIntegrationFallback = async (directCall, integrationCall, id, options = {}) => {
|
|
375
|
+
try {
|
|
376
|
+
const result = await directCall();
|
|
377
|
+
clearIntegrationFallbackStatus(id);
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
const response = error === null || error === void 0 ? void 0 : error.response;
|
|
382
|
+
const status = response === null || response === void 0 ? void 0 : response.status;
|
|
383
|
+
const headers = response === null || response === void 0 ? void 0 : response.headers;
|
|
384
|
+
const hasMarker = !!(headers &&
|
|
385
|
+
(typeof headers.get === 'function'
|
|
386
|
+
? headers.get(UDP_QUERY_RUNTIME_MARKER_HEADER)
|
|
387
|
+
: headers[UDP_QUERY_RUNTIME_MARKER_HEADER]));
|
|
388
|
+
if (shouldFallBackToIntegration(status, hasMarker, options)) {
|
|
389
|
+
console.warn(`Direct UdpQuery execution answered ${status}; falling back to Integration`, error);
|
|
390
|
+
if (status === 503) {
|
|
391
|
+
recordIntegrationFallbackStatus(id, status);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
// Skip the wasted direct attempt for this id for the rest of the page load.
|
|
395
|
+
markIntegrationOnly(id, status);
|
|
396
|
+
}
|
|
397
|
+
return integrationCall();
|
|
398
|
+
}
|
|
399
|
+
throw error;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* Records that a direct execution for this id (apiMethodId or instance id)
|
|
404
|
+
* answered the fallback signal, so subsequent executions this page load skip
|
|
405
|
+
* the wasted direct attempt and go straight to Integration.
|
|
406
|
+
*/
|
|
407
|
+
function markIntegrationOnly(id, status) {
|
|
408
|
+
if (id && !state.integrationOnlyIds.includes(id)) {
|
|
409
|
+
state.integrationOnlyIds = [...state.integrationOnlyIds, id];
|
|
410
|
+
if (typeof status === 'number') {
|
|
411
|
+
state.integrationFallbackStatuses = Object.assign(Object.assign({}, state.integrationFallbackStatuses), { [id]: status });
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function recordIntegrationFallbackStatus(id, status) {
|
|
416
|
+
if (id) {
|
|
417
|
+
state.integrationFallbackStatuses = Object.assign(Object.assign({}, state.integrationFallbackStatuses), { [id]: status });
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function clearIntegrationFallbackStatus(id) {
|
|
421
|
+
if (id && id in state.integrationFallbackStatuses) {
|
|
422
|
+
const rest = Object.assign({}, state.integrationFallbackStatuses);
|
|
423
|
+
delete rest[id];
|
|
424
|
+
state.integrationFallbackStatuses = rest;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* The HTTP status this id's latest direct attempt fell back on (501, 503 or a
|
|
429
|
+
* markerless 404), or undefined when it has not fallen back or its latest
|
|
430
|
+
* direct attempt succeeded. 501/404 also make the id integration-only for the
|
|
431
|
+
* page load, so they stick; a 503 clears on the next direct success.
|
|
432
|
+
*/
|
|
433
|
+
function getIntegrationFallbackStatus(id) {
|
|
434
|
+
return id ? state.integrationFallbackStatuses[id] : undefined;
|
|
435
|
+
}
|
|
436
|
+
function isIntegrationOnly(id) {
|
|
437
|
+
return !!id && state.integrationOnlyIds.includes(id);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Announces an in-flight descriptor fetch, arming the boot barrier: from this
|
|
441
|
+
* call until the routing answer settles (see isExecutionRoutingSettled),
|
|
442
|
+
* whenExecutionRoutingSettled parks executors instead of letting their first
|
|
443
|
+
* query silently fail open to Integration. Idempotent; called by the provider
|
|
444
|
+
* that owns the tenant x product descriptor fetch as soon as it mounts.
|
|
445
|
+
* Whoever calls this MUST guarantee a descriptor write follows (success or
|
|
446
|
+
* failure), and — when that write says direct — a bulk eligibility write too,
|
|
447
|
+
* or parked executors never run.
|
|
448
|
+
*/
|
|
449
|
+
function markQueryExecutionResolving() {
|
|
450
|
+
if (!isExecutionRoutingSettled()) {
|
|
451
|
+
state.descriptorResolving = true;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* The routing question is settled once the descriptor is known and, when it
|
|
456
|
+
* says direct, the bulk eligibility registration has landed as well — before
|
|
457
|
+
* that, every per-id eligibility check would miss and route Integration.
|
|
458
|
+
* An integration (or absent) descriptor settles alone: eligibility is
|
|
459
|
+
* irrelevant on that path.
|
|
460
|
+
*/
|
|
461
|
+
function isExecutionRoutingSettled() {
|
|
462
|
+
var _a;
|
|
463
|
+
return state.descriptorKnown && (((_a = state.queryExecution) === null || _a === void 0 ? void 0 : _a.mode) !== 'direct' || state.eligibilityKnown);
|
|
464
|
+
}
|
|
465
|
+
function releaseBarrierIfSettled() {
|
|
466
|
+
if (isExecutionRoutingSettled()) {
|
|
467
|
+
releaseQueryExecutionResolving();
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* How long a parked executor waits for the routing answer before failing open
|
|
472
|
+
* to Integration.
|
|
473
|
+
*/
|
|
474
|
+
const EXECUTION_ROUTING_SETTLE_TIMEOUT_MS = 10000;
|
|
475
|
+
/**
|
|
476
|
+
* Disarms the boot barrier and releases every parked executor onto whatever
|
|
477
|
+
* routing is known (Integration until a descriptor lands). For a provider that
|
|
478
|
+
* unmounts mid-fetch, and the barrier's own timeout. A descriptor or
|
|
479
|
+
* eligibility write arriving later still takes effect for subsequent queries.
|
|
480
|
+
*/
|
|
481
|
+
function releaseQueryExecutionResolving() {
|
|
482
|
+
state.descriptorResolving = false;
|
|
483
|
+
const waiters = state.descriptorWaiters;
|
|
484
|
+
state.descriptorWaiters = [];
|
|
485
|
+
waiters.forEach((release) => release());
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Starts routing over for a new scope (tenant switch): forgets the descriptor
|
|
489
|
+
* and every per-id Integration fallback, and re-arms the boot barrier so
|
|
490
|
+
* executors park until the new scope's descriptor lands instead of running on
|
|
491
|
+
* the previous one's. The eligible set is kept — it is keyed by the api
|
|
492
|
+
* catalog, and the provider replaces it whenever the catalog changes. Same
|
|
493
|
+
* contract as markQueryExecutionResolving: a descriptor write MUST follow.
|
|
494
|
+
*/
|
|
495
|
+
function resetQueryExecutionRouting() {
|
|
496
|
+
state.queryExecution = null;
|
|
497
|
+
state.descriptorKnown = false;
|
|
498
|
+
state.integrationOnlyIds = [];
|
|
499
|
+
state.integrationFallbackStatuses = {};
|
|
500
|
+
state.descriptorResolving = true;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* The boot barrier: resolves once the routing question is settled for this
|
|
504
|
+
* page load. Immediate when it already is — or when no provider has announced
|
|
505
|
+
* a descriptor fetch, preserving the fail-open-to-Integration behavior for
|
|
506
|
+
* surfaces mounted without one. Never hangs: after
|
|
507
|
+
* EXECUTION_ROUTING_SETTLE_TIMEOUT_MS the barrier disarms and every parked
|
|
508
|
+
* executor fails open.
|
|
509
|
+
*/
|
|
510
|
+
function whenExecutionRoutingSettled(timeoutMs = EXECUTION_ROUTING_SETTLE_TIMEOUT_MS) {
|
|
511
|
+
if (isExecutionRoutingSettled() || !state.descriptorResolving) {
|
|
512
|
+
return Promise.resolve();
|
|
513
|
+
}
|
|
514
|
+
return new Promise((resolve) => {
|
|
515
|
+
const timer = setTimeout(() => {
|
|
516
|
+
console.warn(`Query execution routing did not settle within ${timeoutMs}ms; executing via Integration`);
|
|
517
|
+
releaseQueryExecutionResolving();
|
|
518
|
+
}, timeoutMs);
|
|
519
|
+
state.descriptorWaiters.push(() => {
|
|
520
|
+
clearTimeout(timer);
|
|
521
|
+
resolve();
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Deliberately not persisted (session/local storage): ForceIntegration's
|
|
527
|
+
* kill-switch semantics rely on a fresh descriptor fetch per page load.
|
|
528
|
+
* Also advances the boot barrier — a null or integration write settles it
|
|
529
|
+
* outright (eligibility is irrelevant on that path); a direct write settles it
|
|
530
|
+
* once the bulk eligibility registration has landed too.
|
|
531
|
+
*/
|
|
532
|
+
function setQueryExecutionDescriptor(descriptor) {
|
|
533
|
+
state.queryExecution = descriptor !== null && descriptor !== void 0 ? descriptor : null;
|
|
534
|
+
state.descriptorKnown = true;
|
|
535
|
+
releaseBarrierIfSettled();
|
|
536
|
+
}
|
|
537
|
+
function getQueryExecutionDescriptor() {
|
|
538
|
+
return state.queryExecution;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* apiMethodIds of the catalog's direct-eligible promoted base operations — the
|
|
542
|
+
* per-query half of the routing rule. Populated by the enterprise library from
|
|
543
|
+
* the promoted-method catalog it already fetches at startup. This bulk write
|
|
544
|
+
* (an empty list on a failed catalog fetch included) is the boot barrier's
|
|
545
|
+
* eligibility-known signal; the additive per-entity writes below are not — they
|
|
546
|
+
* cover one entity, so releasing every parked query on them would wrongly send
|
|
547
|
+
* the others to Integration.
|
|
548
|
+
*/
|
|
549
|
+
function setDirectEligibleApiMethodIds(apiMethodIds) {
|
|
550
|
+
state.directEligibleApiMethodIds = (apiMethodIds !== null && apiMethodIds !== void 0 ? apiMethodIds : []).filter((id) => !!id);
|
|
551
|
+
state.eligibilityKnown = true;
|
|
552
|
+
releaseBarrierIfSettled();
|
|
553
|
+
}
|
|
554
|
+
function getDirectEligibleApiMethodIds() {
|
|
555
|
+
return state.directEligibleApiMethodIds;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Additively merges apiMethodIds into the eligible set. Used by the per-entity
|
|
559
|
+
* promoted-method fetches so a page's own entity is registered by the same
|
|
560
|
+
* response that arms its grid — closing the startup race against the bulk
|
|
561
|
+
* catalog fetch (which still replaces the full list when it lands).
|
|
562
|
+
*/
|
|
563
|
+
function addDirectEligibleApiMethodIds(apiMethodIds) {
|
|
564
|
+
const incoming = (apiMethodIds !== null && apiMethodIds !== void 0 ? apiMethodIds : []).filter((id) => !!id);
|
|
565
|
+
if (!incoming.length) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
state.directEligibleApiMethodIds = Array.from(new Set([...state.directEligibleApiMethodIds, ...incoming]));
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* The one place the whole routing rule lives: direct only when the descriptor
|
|
572
|
+
* says direct, carries a product URL, and the query's apiMethodId maps to a
|
|
573
|
+
* direct-eligible promoted base operation. Anything else — including an unset
|
|
574
|
+
* descriptor from a backend that predates the field — resolves to the
|
|
575
|
+
* Integration path. On direct failure the executor seams apply the narrow
|
|
576
|
+
* {@link shouldFallBackToIntegration} contract (501/503, markerless 404); every
|
|
577
|
+
* other failure surfaces, and ForceIntegration on the product version remains
|
|
578
|
+
* the operational recovery path.
|
|
579
|
+
*/
|
|
580
|
+
function resolveExecutionTarget(apiMethodId) {
|
|
581
|
+
const descriptor = state.queryExecution;
|
|
582
|
+
if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.mode) === 'direct' &&
|
|
583
|
+
descriptor.url &&
|
|
584
|
+
apiMethodId &&
|
|
585
|
+
!isIntegrationOnly(apiMethodId) &&
|
|
586
|
+
state.directEligibleApiMethodIds.includes(apiMethodId)) {
|
|
587
|
+
const url = trimTrailingSlashes(descriptor.url);
|
|
588
|
+
return { mode: 'direct', url, requestUrl: buildDirectAdhocRequestUrl(url, apiMethodId) };
|
|
589
|
+
}
|
|
590
|
+
return { mode: 'integration' };
|
|
591
|
+
}
|
|
592
|
+
|
|
260
593
|
// Function for the first API call
|
|
261
594
|
const getApiCatalogAndProduct = async () => {
|
|
262
595
|
const { baseURL } = await getBaseUrls();
|
|
@@ -276,7 +609,7 @@ let prefetchedQueryAdHoc;
|
|
|
276
609
|
const executeQueryAdHoc = (data, apiMethodId, apiBase, prefetch = false) => {
|
|
277
610
|
const args = [data, apiMethodId, tenantUtils.getCurrentTenantId(), apiBase != 'hotlist'];
|
|
278
611
|
if (!prefetch && prefetchedQueryAdHoc) {
|
|
279
|
-
if (
|
|
612
|
+
if (isEqual__default.default(prefetchedQueryAdHoc.args, args)) {
|
|
280
613
|
const { response } = prefetchedQueryAdHoc;
|
|
281
614
|
console.info(`Using prefetch for /apimethod/executeQueryAdHoc/${apiMethodId} prefetch`, prefetchedQueryAdHoc.args, args);
|
|
282
615
|
prefetchedQueryAdHoc = undefined;
|
|
@@ -287,11 +620,25 @@ const executeQueryAdHoc = (data, apiMethodId, apiBase, prefetch = false) => {
|
|
|
287
620
|
prefetchedQueryAdHoc = undefined;
|
|
288
621
|
}
|
|
289
622
|
}
|
|
290
|
-
const response = getBaseUrls().then(({ baseURL, baseURLHost }) => {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
623
|
+
const response = getBaseUrls().then(async ({ baseURL, baseURLHost }) => {
|
|
624
|
+
// Direct-if-eligible routing (UNT-6403): when the tenant x product execution
|
|
625
|
+
// descriptor says "direct" and this apiMethodId maps to a direct-eligible
|
|
626
|
+
// promoted base operation, the ad hoc query executes against the product's
|
|
627
|
+
// UdpQuery endpoint, with the narrow Integration fallback for builds whose
|
|
628
|
+
// runtime predates the operation. The boot barrier holds a page's first
|
|
629
|
+
// queries until the provider's descriptor fetch settles, so a reload does
|
|
630
|
+
// not silently route them to Integration.
|
|
631
|
+
if (apiBase != 'hotlist') {
|
|
632
|
+
await whenExecutionRoutingSettled();
|
|
633
|
+
}
|
|
634
|
+
const target = apiBase != 'hotlist' ? resolveExecutionTarget(apiMethodId) : { mode: 'integration' };
|
|
635
|
+
const integrationUrl = apiBase == 'hotlist'
|
|
636
|
+
? `${baseURLHost}/UdpHotList/containingRecord`
|
|
637
|
+
: `${baseURL}/apimethod/executeQueryAdHoc/${apiMethodId}`;
|
|
638
|
+
if (target.mode === 'direct') {
|
|
639
|
+
return directCallWithIntegrationFallback(() => makeApiCall.makeApiCall('POST', target.requestUrl, data), () => makeApiCall.makeApiCall('POST', integrationUrl, data), apiMethodId);
|
|
640
|
+
}
|
|
641
|
+
return makeApiCall.makeApiCall('POST', integrationUrl, data);
|
|
295
642
|
});
|
|
296
643
|
if (prefetch) {
|
|
297
644
|
console.info(`Prefetching /apimethod/executeQueryAdHoc/${apiMethodId}`);
|
|
@@ -311,10 +658,31 @@ const getApiCatalogById = async (apiCatalogId) => {
|
|
|
311
658
|
const executeQueryWithParameters = async (data, apiMethodId) => {
|
|
312
659
|
console.log('executeQueryWithParameters called', apiMethodId);
|
|
313
660
|
const { baseURL } = await getBaseUrls();
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
661
|
+
const integrationUrl = `${baseURL}/apimethod/executeQueryWithParameters/${apiMethodId}`;
|
|
662
|
+
// Direct-if-eligible routing (UNT-6403): the request body contract is identical
|
|
663
|
+
// on both paths (a flat name→value map plus an optional requestBody entry).
|
|
664
|
+
// Boot barrier: see executeQueryAdHoc.
|
|
665
|
+
await whenExecutionRoutingSettled();
|
|
666
|
+
const target = resolveExecutionTarget(apiMethodId);
|
|
667
|
+
if (target.mode === 'direct') {
|
|
668
|
+
return directCallWithIntegrationFallback(() => makeApiCall.makeApiCall('POST', buildDirectExecuteWithParametersUrl(target.url, apiMethodId), data), () => makeApiCall.makeApiCall('POST', integrationUrl, data), apiMethodId, { mayWrite: true });
|
|
669
|
+
}
|
|
670
|
+
return makeApiCall.makeApiCall('POST', integrationUrl, data);
|
|
671
|
+
};
|
|
672
|
+
/**
|
|
673
|
+
* Ad hoc execution against a caller-resolved direct UdpQuery URL, for callers
|
|
674
|
+
* that route outside the hosting product's execution store (e.g. Data Builder,
|
|
675
|
+
* which builds queries against any product). Applies the same migration-window
|
|
676
|
+
* fallback contract as executeQueryAdHoc, with Integration's ad hoc endpoint
|
|
677
|
+
* for this apiMethodId as the fallback target.
|
|
678
|
+
*/
|
|
679
|
+
const executeDirectQueryAdHoc = async (data, apiMethodId, directRequestUrl) => {
|
|
680
|
+
const { baseURL } = await getBaseUrls();
|
|
681
|
+
const integrationUrl = `${baseURL}/apimethod/executeQueryAdHoc/${apiMethodId}`;
|
|
682
|
+
if (isIntegrationOnly(apiMethodId)) {
|
|
683
|
+
return makeApiCall.makeApiCall('POST', integrationUrl, data);
|
|
684
|
+
}
|
|
685
|
+
return directCallWithIntegrationFallback(() => makeApiCall.makeApiCall('POST', directRequestUrl, data), () => makeApiCall.makeApiCall('POST', integrationUrl, data), apiMethodId);
|
|
318
686
|
};
|
|
319
687
|
class QueryResult {
|
|
320
688
|
constructor() {
|
|
@@ -370,7 +738,9 @@ function getCleanData(data, lookupsMap) {
|
|
|
370
738
|
const keys = (_a = lookup.udpLookupUdpLookupKey) !== null && _a !== void 0 ? _a : (lookup.keyName ? [{ name: lookup.keyName }] : []);
|
|
371
739
|
let temp = (_b = lookup === null || lookup === void 0 ? void 0 : lookup.data) === null || _b === void 0 ? void 0 : _b.find(item => item[lookup.valueName] === currentValue);
|
|
372
740
|
if (temp != null)
|
|
373
|
-
keys.forEach(k => {
|
|
741
|
+
keys.forEach(k => {
|
|
742
|
+
cleanData[index][k.name] = temp[k.name];
|
|
743
|
+
});
|
|
374
744
|
});
|
|
375
745
|
}
|
|
376
746
|
else if (cleanData[attribute]) {
|
|
@@ -379,7 +749,9 @@ function getCleanData(data, lookupsMap) {
|
|
|
379
749
|
const keys = (_a = lookup.udpLookupUdpLookupKey) !== null && _a !== void 0 ? _a : (lookup.keyName ? [{ name: lookup.keyName }] : []);
|
|
380
750
|
let temp = lookup.data.find(item => item[lookup.valueName] === currentValue);
|
|
381
751
|
if (temp != null)
|
|
382
|
-
keys.forEach(k => {
|
|
752
|
+
keys.forEach(k => {
|
|
753
|
+
cleanData[k.name] = temp[k.name];
|
|
754
|
+
});
|
|
383
755
|
/* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
|
|
384
756
|
}
|
|
385
757
|
});
|
|
@@ -627,11 +999,20 @@ const removeRecordFromHotlist = async (hotlistID) => {
|
|
|
627
999
|
return makeApiCall.makeApiCall('DELETE', url, null, true);
|
|
628
1000
|
};
|
|
629
1001
|
|
|
1002
|
+
exports.DIRECT_ELIGIBLE_BASE_OPERATION_TYPE_IDS = DIRECT_ELIGIBLE_BASE_OPERATION_TYPE_IDS;
|
|
1003
|
+
exports.EXECUTION_ROUTING_SETTLE_TIMEOUT_MS = EXECUTION_ROUTING_SETTLE_TIMEOUT_MS;
|
|
1004
|
+
exports.UDP_QUERY_RUNTIME_MARKER_HEADER = UDP_QUERY_RUNTIME_MARKER_HEADER;
|
|
1005
|
+
exports.addDirectEligibleApiMethodIds = addDirectEligibleApiMethodIds;
|
|
630
1006
|
exports.addRecordToAHotlist = addRecordToAHotlist;
|
|
1007
|
+
exports.buildDirectAdhocRequestUrl = buildDirectAdhocRequestUrl;
|
|
1008
|
+
exports.buildDirectExecuteInstanceUrl = buildDirectExecuteInstanceUrl;
|
|
1009
|
+
exports.buildDirectExecuteWithParametersUrl = buildDirectExecuteWithParametersUrl;
|
|
631
1010
|
exports.createAHotlist = createAHotlist;
|
|
632
1011
|
exports.createStore = createStore;
|
|
633
1012
|
exports.deleteAHotlist = deleteAHotlist;
|
|
634
1013
|
exports.deleteSelectedView = deleteSelectedView;
|
|
1014
|
+
exports.directCallWithIntegrationFallback = directCallWithIntegrationFallback;
|
|
1015
|
+
exports.executeDirectQueryAdHoc = executeDirectQueryAdHoc;
|
|
635
1016
|
exports.executeQueryAdHoc = executeQueryAdHoc;
|
|
636
1017
|
exports.executeQueryAdHocAndMapLookups = executeQueryAdHocAndMapLookups;
|
|
637
1018
|
exports.executeQueryWithParameters = executeQueryWithParameters;
|
|
@@ -643,12 +1024,25 @@ exports.getApiMethodInstance = getApiMethodInstance;
|
|
|
643
1024
|
exports.getAvailableGridActions = getAvailableGridActions;
|
|
644
1025
|
exports.getAvailableViews = getAvailableViews;
|
|
645
1026
|
exports.getCleanData = getCleanData;
|
|
1027
|
+
exports.getDirectEligibleApiMethodIds = getDirectEligibleApiMethodIds;
|
|
646
1028
|
exports.getGridViewsWithConfigurations = getGridViewsWithConfigurations;
|
|
1029
|
+
exports.getIntegrationFallbackStatus = getIntegrationFallbackStatus;
|
|
647
1030
|
exports.getPromotedLookupMethod = getPromotedLookupMethod;
|
|
648
1031
|
exports.getPromotedMethodEntities = getPromotedMethodEntities;
|
|
1032
|
+
exports.getQueryExecutionDescriptor = getQueryExecutionDescriptor;
|
|
649
1033
|
exports.getSelectedView = getSelectedView;
|
|
1034
|
+
exports.isIntegrationOnly = isIntegrationOnly;
|
|
650
1035
|
exports.loadAHotlist = loadAHotlist;
|
|
1036
|
+
exports.markIntegrationOnly = markIntegrationOnly;
|
|
1037
|
+
exports.markQueryExecutionResolving = markQueryExecutionResolving;
|
|
1038
|
+
exports.releaseQueryExecutionResolving = releaseQueryExecutionResolving;
|
|
651
1039
|
exports.removeRecordFromHotlist = removeRecordFromHotlist;
|
|
1040
|
+
exports.resetQueryExecutionRouting = resetQueryExecutionRouting;
|
|
1041
|
+
exports.resolveExecutionTarget = resolveExecutionTarget;
|
|
652
1042
|
exports.saveView = saveView;
|
|
1043
|
+
exports.setDirectEligibleApiMethodIds = setDirectEligibleApiMethodIds;
|
|
1044
|
+
exports.setQueryExecutionDescriptor = setQueryExecutionDescriptor;
|
|
1045
|
+
exports.shouldFallBackToIntegration = shouldFallBackToIntegration;
|
|
653
1046
|
exports.updateView = updateView;
|
|
654
1047
|
exports.updateViewAndConfigurations = updateViewAndConfigurations;
|
|
1048
|
+
exports.whenExecutionRoutingSettled = whenExecutionRoutingSettled;
|