@memberjunction/global 2.112.0 → 2.113.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.
Files changed (117) hide show
  1. package/package.json +1 -1
  2. package/dist/Core.d.ts +0 -29
  3. package/dist/Core.d.ts.map +0 -1
  4. package/dist/Core.js +0 -58
  5. package/dist/Core.js.map +0 -1
  6. package/dist/generic/QueryCache.d.ts +0 -85
  7. package/dist/generic/QueryCache.d.ts.map +0 -1
  8. package/dist/generic/QueryCache.js +0 -198
  9. package/dist/generic/QueryCache.js.map +0 -1
  10. package/dist/generic/QueryCacheConfig.d.ts +0 -72
  11. package/dist/generic/QueryCacheConfig.d.ts.map +0 -1
  12. package/dist/generic/QueryCacheConfig.js +0 -3
  13. package/dist/generic/QueryCacheConfig.js.map +0 -1
  14. package/dist/generic/applicationInfo.d.ts +0 -138
  15. package/dist/generic/applicationInfo.d.ts.map +0 -1
  16. package/dist/generic/applicationInfo.js +0 -177
  17. package/dist/generic/applicationInfo.js.map +0 -1
  18. package/dist/generic/authEvaluator.d.ts +0 -25
  19. package/dist/generic/authEvaluator.d.ts.map +0 -1
  20. package/dist/generic/authEvaluator.js +0 -49
  21. package/dist/generic/authEvaluator.js.map +0 -1
  22. package/dist/generic/authTypes.d.ts +0 -193
  23. package/dist/generic/authTypes.d.ts.map +0 -1
  24. package/dist/generic/authTypes.js +0 -19
  25. package/dist/generic/authTypes.js.map +0 -1
  26. package/dist/generic/baseEngine.d.ts +0 -260
  27. package/dist/generic/baseEngine.d.ts.map +0 -1
  28. package/dist/generic/baseEngine.js +0 -510
  29. package/dist/generic/baseEngine.js.map +0 -1
  30. package/dist/generic/baseEntity.d.ts +0 -691
  31. package/dist/generic/baseEntity.d.ts.map +0 -1
  32. package/dist/generic/baseEntity.js +0 -1688
  33. package/dist/generic/baseEntity.js.map +0 -1
  34. package/dist/generic/baseInfo.d.ts +0 -24
  35. package/dist/generic/baseInfo.d.ts.map +0 -1
  36. package/dist/generic/baseInfo.js +0 -53
  37. package/dist/generic/baseInfo.js.map +0 -1
  38. package/dist/generic/compositeKey.d.ts +0 -206
  39. package/dist/generic/compositeKey.d.ts.map +0 -1
  40. package/dist/generic/compositeKey.js +0 -412
  41. package/dist/generic/compositeKey.js.map +0 -1
  42. package/dist/generic/databaseProviderBase.d.ts +0 -46
  43. package/dist/generic/databaseProviderBase.d.ts.map +0 -1
  44. package/dist/generic/databaseProviderBase.js +0 -14
  45. package/dist/generic/databaseProviderBase.js.map +0 -1
  46. package/dist/generic/entityInfo.d.ts +0 -983
  47. package/dist/generic/entityInfo.d.ts.map +0 -1
  48. package/dist/generic/entityInfo.js +0 -1401
  49. package/dist/generic/entityInfo.js.map +0 -1
  50. package/dist/generic/explorerNavigationItem.d.ts +0 -20
  51. package/dist/generic/explorerNavigationItem.d.ts.map +0 -1
  52. package/dist/generic/explorerNavigationItem.js +0 -29
  53. package/dist/generic/explorerNavigationItem.js.map +0 -1
  54. package/dist/generic/interfaces.d.ts +0 -610
  55. package/dist/generic/interfaces.d.ts.map +0 -1
  56. package/dist/generic/interfaces.js +0 -211
  57. package/dist/generic/interfaces.js.map +0 -1
  58. package/dist/generic/libraryInfo.d.ts +0 -40
  59. package/dist/generic/libraryInfo.d.ts.map +0 -1
  60. package/dist/generic/libraryInfo.js +0 -56
  61. package/dist/generic/libraryInfo.js.map +0 -1
  62. package/dist/generic/logging.d.ts +0 -179
  63. package/dist/generic/logging.d.ts.map +0 -1
  64. package/dist/generic/logging.js +0 -382
  65. package/dist/generic/logging.js.map +0 -1
  66. package/dist/generic/metadata.d.ts +0 -305
  67. package/dist/generic/metadata.d.ts.map +0 -1
  68. package/dist/generic/metadata.js +0 -454
  69. package/dist/generic/metadata.js.map +0 -1
  70. package/dist/generic/metadataUtil.d.ts +0 -8
  71. package/dist/generic/metadataUtil.d.ts.map +0 -1
  72. package/dist/generic/metadataUtil.js +0 -36
  73. package/dist/generic/metadataUtil.js.map +0 -1
  74. package/dist/generic/providerBase.d.ts +0 -546
  75. package/dist/generic/providerBase.d.ts.map +0 -1
  76. package/dist/generic/providerBase.js +0 -999
  77. package/dist/generic/providerBase.js.map +0 -1
  78. package/dist/generic/queryInfo.d.ts +0 -460
  79. package/dist/generic/queryInfo.d.ts.map +0 -1
  80. package/dist/generic/queryInfo.js +0 -633
  81. package/dist/generic/queryInfo.js.map +0 -1
  82. package/dist/generic/querySQLFilters.d.ts +0 -54
  83. package/dist/generic/querySQLFilters.d.ts.map +0 -1
  84. package/dist/generic/querySQLFilters.js +0 -84
  85. package/dist/generic/querySQLFilters.js.map +0 -1
  86. package/dist/generic/runQuery.d.ts +0 -96
  87. package/dist/generic/runQuery.d.ts.map +0 -1
  88. package/dist/generic/runQuery.js +0 -66
  89. package/dist/generic/runQuery.js.map +0 -1
  90. package/dist/generic/runQuerySQLFilterImplementations.d.ts +0 -51
  91. package/dist/generic/runQuerySQLFilterImplementations.d.ts.map +0 -1
  92. package/dist/generic/runQuerySQLFilterImplementations.js +0 -238
  93. package/dist/generic/runQuerySQLFilterImplementations.js.map +0 -1
  94. package/dist/generic/runReport.d.ts +0 -25
  95. package/dist/generic/runReport.d.ts.map +0 -1
  96. package/dist/generic/runReport.js +0 -42
  97. package/dist/generic/runReport.js.map +0 -1
  98. package/dist/generic/securityInfo.d.ts +0 -355
  99. package/dist/generic/securityInfo.d.ts.map +0 -1
  100. package/dist/generic/securityInfo.js +0 -425
  101. package/dist/generic/securityInfo.js.map +0 -1
  102. package/dist/generic/transactionGroup.d.ts +0 -184
  103. package/dist/generic/transactionGroup.d.ts.map +0 -1
  104. package/dist/generic/transactionGroup.js +0 -357
  105. package/dist/generic/transactionGroup.js.map +0 -1
  106. package/dist/generic/util.d.ts +0 -81
  107. package/dist/generic/util.d.ts.map +0 -1
  108. package/dist/generic/util.js +0 -301
  109. package/dist/generic/util.js.map +0 -1
  110. package/dist/views/runView.d.ts +0 -150
  111. package/dist/views/runView.d.ts.map +0 -1
  112. package/dist/views/runView.js +0 -100
  113. package/dist/views/runView.js.map +0 -1
  114. package/dist/views/viewInfo.d.ts +0 -121
  115. package/dist/views/viewInfo.d.ts.map +0 -1
  116. package/dist/views/viewInfo.js +0 -182
  117. package/dist/views/viewInfo.js.map +0 -1
@@ -1,999 +0,0 @@
1
- "use strict";
2
- var _a;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.ProviderBase = exports.AllMetadataArrays = exports.MetadataFromSimpleObjectWithoutUser = exports.MetadataFromSimpleObject = void 0;
5
- const baseEntity_1 = require("./baseEntity");
6
- const entityInfo_1 = require("./entityInfo");
7
- const interfaces_1 = require("./interfaces");
8
- const applicationInfo_1 = require("../generic/applicationInfo");
9
- const securityInfo_1 = require("./securityInfo");
10
- const logging_1 = require("./logging");
11
- const queryInfo_1 = require("./queryInfo");
12
- const libraryInfo_1 = require("./libraryInfo");
13
- const compositeKey_1 = require("./compositeKey");
14
- const explorerNavigationItem_1 = require("./explorerNavigationItem");
15
- const metadata_1 = require("./metadata");
16
- const runView_1 = require("../views/runView");
17
- const Global_1 = require("../Global");
18
- /**
19
- * Creates a new instance of AllMetadata from a simple object.
20
- * Handles deserialization and proper instantiation of all metadata classes.
21
- * @param data - The raw metadata object to convert
22
- * @param md - The metadata provider for context
23
- * @returns A fully populated AllMetadata instance with proper type instances
24
- */
25
- function MetadataFromSimpleObject(data, md) {
26
- try {
27
- const newObject = MetadataFromSimpleObjectWithoutUser(data, md);
28
- newObject.CurrentUser = data.CurrentUser ? new securityInfo_1.UserInfo(md, data.CurrentUser) : null;
29
- return newObject;
30
- }
31
- catch (e) {
32
- (0, logging_1.LogError)(e);
33
- }
34
- }
35
- exports.MetadataFromSimpleObject = MetadataFromSimpleObject;
36
- /**
37
- * Creates a new instance of AllMetadata from a simple object, but does NOT set the CurrentUser property
38
- * Handles deserialization and proper instantiation of all metadata classes.
39
- * @param data - The raw metadata object to convert
40
- * @param md - The metadata provider for context
41
- * @returns A fully populated AllMetadata instance with proper type instances
42
- */
43
- function MetadataFromSimpleObjectWithoutUser(data, md) {
44
- try {
45
- const returnMetadata = new interfaces_1.AllMetadata();
46
- // now iterate through the AllMetadataMapping array and construct the return type
47
- for (let m of exports.AllMetadataArrays) {
48
- let simpleKey = m.key;
49
- if (!data.hasOwnProperty(simpleKey)) {
50
- simpleKey = simpleKey.substring(3); // remove the All prefix
51
- }
52
- if (data.hasOwnProperty(simpleKey)) {
53
- // at this point, only do this particular property if we have a match, it is either prefixed with All or not
54
- // for example in our strongly typed AllMetadata class we have AllQueryCategories, but in the simple allMetadata object we have QueryCategories
55
- // so we need to check for both which is what the above is doing.
56
- // Build the array of the correct type and initialize with the simple object
57
- returnMetadata[m.key] = data[simpleKey].map((d) => new m.class(d, md));
58
- }
59
- }
60
- return returnMetadata;
61
- }
62
- catch (e) {
63
- (0, logging_1.LogError)(e);
64
- }
65
- }
66
- exports.MetadataFromSimpleObjectWithoutUser = MetadataFromSimpleObjectWithoutUser;
67
- /**
68
- * This is a list of all metadata classes that are used in the AllMetadata class.
69
- * Used to automatically determine the class type when deserializing the metadata and
70
- * for iterating through all metadata collections.
71
- * Each entry maps a property key to its corresponding class constructor.
72
- */
73
- exports.AllMetadataArrays = [
74
- { key: 'AllEntities', class: entityInfo_1.EntityInfo },
75
- { key: 'AllApplications', class: applicationInfo_1.ApplicationInfo },
76
- { key: 'AllRoles', class: securityInfo_1.RoleInfo },
77
- { key: 'AllRowLevelSecurityFilters', class: securityInfo_1.RowLevelSecurityFilterInfo },
78
- { key: 'AllAuditLogTypes', class: securityInfo_1.AuditLogTypeInfo },
79
- { key: 'AllAuthorizations', class: securityInfo_1.AuthorizationInfo },
80
- { key: 'AllQueryCategories', class: queryInfo_1.QueryCategoryInfo },
81
- { key: 'AllQueries', class: queryInfo_1.QueryInfo },
82
- { key: 'AllQueryFields', class: queryInfo_1.QueryFieldInfo },
83
- { key: 'AllQueryPermissions', class: queryInfo_1.QueryPermissionInfo },
84
- { key: 'AllQueryEntities', class: queryInfo_1.QueryEntityInfo },
85
- { key: 'AllQueryParameters', class: queryInfo_1.QueryParameterInfo },
86
- { key: 'AllEntityDocumentTypes', class: entityInfo_1.EntityDocumentTypeInfo },
87
- { key: 'AllLibraries', class: libraryInfo_1.LibraryInfo },
88
- { key: 'AllExplorerNavigationItems', class: explorerNavigationItem_1.ExplorerNavigationItem },
89
- ];
90
- /**
91
- * Base class for all metadata providers in MemberJunction.
92
- * Implements common functionality for metadata caching, refresh, and dataset management.
93
- * Subclasses must implement abstract methods for provider-specific operations.
94
- */
95
- class ProviderBase {
96
- constructor() {
97
- this._localMetadata = new interfaces_1.AllMetadata();
98
- this._refresh = false;
99
- this._cachedVisibleExplorerNavigationItems = null;
100
- }
101
- /**
102
- * Used to check to see if the entity in question is active or not
103
- * If it is not active, it will throw an exception or log a warning depending on the status of the entity being
104
- * either Deprecated or Disabled.
105
- * @param entityName
106
- * @param callerName
107
- */
108
- async EntityStatusCheck(params, callerName) {
109
- const entityName = await runView_1.RunView.GetEntityNameFromRunViewParams(params, this);
110
- const entity = this.Entities.find((e) => e.Name.trim().toLowerCase() === entityName?.trim().toLowerCase());
111
- if (!entity) {
112
- throw new Error(`Entity ${entityName} not found in metadata`);
113
- }
114
- entityInfo_1.EntityInfo.AssertEntityActiveStatus(entity, callerName);
115
- }
116
- /**
117
- * Base class pre-processor that all sub-classes should call before they start their RunView process
118
- * @param params
119
- * @param contextUser
120
- */
121
- async PreProcessRunView(params, contextUser) {
122
- await this.EntityStatusCheck(params, 'PreProcessRunView');
123
- // FIRST, if the resultType is entity_object, we need to run the view with ALL fields in the entity
124
- // so that we can get the data to populate the entity object with.
125
- if (params.ResultType === 'entity_object') {
126
- // we need to get the entity definition and then get all the fields for it
127
- const entity = this.Entities.find((e) => e.Name.trim().toLowerCase() === params.EntityName.trim().toLowerCase());
128
- if (!entity)
129
- throw new Error(`Entity ${params.EntityName} not found in metadata`);
130
- params.Fields = entity.Fields.map((f) => f.Name); // just override whatever was passed in with all the fields - or if nothing was passed in, we set it. For loading the entity object, we need ALL the fields.
131
- }
132
- }
133
- /**
134
- * Base class post-processor that all sub-classes should call after they finish their RunView process
135
- * @param params
136
- * @param contextUser
137
- * @returns
138
- */
139
- async PostProcessRunView(result, params, contextUser) {
140
- // Transform the result set into BaseEntity-derived objects, if needed
141
- await this.TransformSimpleObjectToEntityObject(params, result, contextUser);
142
- }
143
- /**
144
- * Base class implementation for handling pre-processing of RunViews() each sub-class should call this
145
- * within their RunViews() method implementation
146
- * @param params
147
- * @param contextUser
148
- * @returns
149
- */
150
- async PreProcessRunViews(params, contextUser) {
151
- if (params && params.length > 0) {
152
- for (const param of params) {
153
- this.EntityStatusCheck(param, 'PreProcessRunViews');
154
- // FIRST, if the resultType is entity_object, we need to run the view with ALL fields in the entity
155
- // so that we can get the data to populate the entity object with.
156
- if (param.ResultType === 'entity_object') {
157
- // we need to get the entity definition and then get all the fields for it
158
- const entity = this.Entities.find((e) => e.Name.trim().toLowerCase() === param.EntityName.trim().toLowerCase());
159
- if (!entity) {
160
- throw new Error(`Entity ${param.EntityName} not found in metadata`);
161
- }
162
- param.Fields = entity.Fields.map((f) => f.Name); // just override whatever was passed in with all the fields - or if nothing was passed in, we set it. For loading the entity object, we need ALL the fields.
163
- }
164
- }
165
- }
166
- }
167
- /**
168
- * Base class utilty method that should be called after each sub-class handles its internal RunViews() process before returning results
169
- * This handles the optional conversion of simple objects to entity objects for each requested view depending on if the params requests
170
- * a result_type === 'entity_object'
171
- * @param results
172
- * @param params
173
- * @param contextUser
174
- */
175
- async PostProcessRunViews(results, params, contextUser) {
176
- if (params && params.length > 0) {
177
- const promises = [];
178
- for (let i = 0; i < results.length; i++) {
179
- promises.push(this.TransformSimpleObjectToEntityObject(params[i], results[i], contextUser));
180
- }
181
- // await the promises for all transformations
182
- await Promise.all(promises);
183
- }
184
- }
185
- /**
186
- * Transforms the result set from simple objects to entity objects if needed.
187
- * @param param - The RunViewParams used for the request
188
- * @param result - The RunViewResult returned from the request
189
- * @param contextUser - The user context for permissions
190
- */
191
- async TransformSimpleObjectToEntityObject(param, result, contextUser) {
192
- // only if needed (e.g. ResultType==='entity_object'), transform the result set into BaseEntity-derived objects
193
- if (param.ResultType === 'entity_object' && result && result.Success) {
194
- // we need to transform each of the items in the result set into a BaseEntity-derived object
195
- // Create entities and load data in parallel for better performance
196
- const entityPromises = result.Results.map(async (item) => {
197
- if (item instanceof baseEntity_1.BaseEntity || typeof item.Save === 'function') {
198
- // the second check is a "duck-typing" check in case we have different runtime
199
- // loading sources where the instanceof will fail
200
- return item;
201
- }
202
- else {
203
- // not a base entity sub-class already so convert
204
- const entity = await this.GetEntityObject(param.EntityName, contextUser);
205
- await entity.LoadFromData(item);
206
- return entity;
207
- }
208
- });
209
- result.Results = await Promise.all(entityPromises);
210
- }
211
- }
212
- /**
213
- * Returns the currently loaded local metadata from within the instance
214
- */
215
- get AllMetadata() {
216
- return this._localMetadata;
217
- }
218
- /**
219
- * Configures the provider with the specified configuration data.
220
- * Handles metadata refresh if needed and initializes the provider.
221
- * @param data - Configuration including schema filters and connection info
222
- * @returns True if configuration was successful
223
- */
224
- async Config(data, providerToUse) {
225
- this._ConfigData = data;
226
- // first, let's check to see if we have an existing Metadata.Provider registered, if so
227
- // unless our data.IgnoreExistingMetadata is set to true, we will not refresh the metadata
228
- if (metadata_1.Metadata.Provider && !data.IgnoreExistingMetadata) {
229
- // we have an existing globally registered provider AND we are not
230
- // requested to ignore the existing metadata, so we will not refresh it
231
- if (this.CopyMetadataFromGlobalProvider()) {
232
- return true; // we're done, if we fail here, we keep going and do normal logic
233
- }
234
- }
235
- if (this._refresh || (await this.CheckToSeeIfRefreshNeeded(providerToUse))) {
236
- // either a hard refresh flag was set within Refresh(), or LocalMetadata is Obsolete
237
- // first, make sure we reset the flag to false so that if another call to this function happens
238
- // while we are waiting for the async call to finish, we dont do it again
239
- this._refresh = false;
240
- // start with fresh metadata
241
- this._localMetadata = new interfaces_1.AllMetadata();
242
- this._cachedVisibleExplorerNavigationItems = null; // reset this so it gets rebuilt next time it is requested
243
- const start = new Date().getTime();
244
- const res = await this.GetAllMetadata(providerToUse);
245
- const end = new Date().getTime();
246
- (0, logging_1.LogStatus)(`GetAllMetadata() took ${end - start} ms`);
247
- if (res) {
248
- this.UpdateLocalMetadata(res);
249
- this._latestLocalMetadataTimestamps = this._latestRemoteMetadataTimestamps; // update this since we just used server to get all the stuff
250
- await this.SaveLocalMetadataToStorage();
251
- }
252
- }
253
- return true;
254
- }
255
- CloneAllMetadata(toClone) {
256
- // we need to create a copy but can't do it the standard way becuase we need object instances
257
- // for various things like EntityInfo
258
- const newmd = MetadataFromSimpleObjectWithoutUser(toClone, this);
259
- newmd.CurrentUser = this.CurrentUser;
260
- return newmd;
261
- }
262
- /**
263
- * Copies metadata from the global provider to the local instance.
264
- * This is used to ensure that the local instance has the latest metadata
265
- * information available without having to reload it from the server.
266
- */
267
- CopyMetadataFromGlobalProvider() {
268
- try {
269
- if (metadata_1.Metadata.Provider && metadata_1.Metadata.Provider !== this && metadata_1.Metadata.Provider.AllMetadata) {
270
- this._localMetadata = this.CloneAllMetadata(metadata_1.Metadata.Provider.AllMetadata);
271
- return true;
272
- }
273
- return false;
274
- }
275
- catch (e) {
276
- (0, logging_1.LogError)(`Failed to copy metadata from global provider: ${e.message}`);
277
- return false; // if we fail to copy the metadata, we will return false
278
- }
279
- }
280
- /**
281
- * Builds dataset filters based on the provider configuration.
282
- * Ensures MJ Core schema is always included and never excluded.
283
- * @returns Array of filters to apply when loading metadata
284
- */
285
- BuildDatasetFilterFromConfig() {
286
- // setup the schema filters as needed
287
- const f = [];
288
- // make sure that the MJ Core schema is always included if includeSchemas are provided because if the user doesn't include them stuff will break
289
- const includeSchemaList = this.ConfigData.IncludeSchemas;
290
- const excludeSchemaList = this.ConfigData.ExcludeSchemas;
291
- const mjcSchema = this.ConfigData.MJCoreSchemaName;
292
- // check to see if the MJ Core schema is already in the list, if not add it
293
- // TODO: The logic here doesn't match the comment above
294
- if (includeSchemaList && includeSchemaList.length > 0 && includeSchemaList.indexOf(mjcSchema) === -1)
295
- includeSchemaList.push(mjcSchema);
296
- // check to make sure that if exclude schemas are provided, the list DOES NOT include the MJ Core schema, if it does, remove it
297
- if (excludeSchemaList && excludeSchemaList.length > 0 && excludeSchemaList.indexOf(mjcSchema) !== -1) {
298
- const index = excludeSchemaList.indexOf(mjcSchema);
299
- excludeSchemaList.splice(index, 1);
300
- (0, logging_1.LogStatus)(`Removed MJ Core schema (${mjcSchema}) from ExcludeSchemas list because it is required for the API to function correctly`);
301
- }
302
- let schemaFilter = '';
303
- if (includeSchemaList && includeSchemaList.length > 0) {
304
- schemaFilter = 'SchemaName IN (' + includeSchemaList.map((s) => `'${s}'`).join(',') + ')';
305
- }
306
- if (excludeSchemaList && excludeSchemaList.length > 0) {
307
- schemaFilter =
308
- (schemaFilter.length > 0 ? ' AND ' : '') + 'SchemaName NOT IN (' + excludeSchemaList.map((s) => `'${s}'`).join(',') + ')';
309
- }
310
- if (schemaFilter.length > 0) {
311
- f.push({ ItemCode: 'Entities', Filter: schemaFilter });
312
- f.push({ ItemCode: 'EntityFields', Filter: schemaFilter });
313
- }
314
- return f;
315
- }
316
- /**
317
- * Retrieves all metadata from the server and constructs typed instances.
318
- * Uses the MJ_Metadata dataset for efficient bulk loading.
319
- * @returns Complete metadata collection with all relationships
320
- */
321
- async GetAllMetadata(providerToUse) {
322
- try {
323
- // we are now using datasets instead of the custom metadata to GraphQL to simplify GraphQL's work as it was very slow preivously
324
- //const start1 = new Date().getTime();
325
- const f = this.BuildDatasetFilterFromConfig();
326
- // Get the dataset and cache it for anyone else who wants to use it
327
- const d = await this.GetDatasetByName(_a._mjMetadataDatasetName, f.length > 0 ? f : null, this.CurrentUser, providerToUse);
328
- if (d && d.Success) {
329
- // cache the dataset for anyone who wants to use it
330
- await this.CacheDataset(_a._mjMetadataDatasetName, f.length > 0 ? f : null, d);
331
- // got the results, let's build our response in the format we need
332
- const simpleMetadata = {};
333
- for (let r of d.Results) {
334
- simpleMetadata[r.Code] = r.Results;
335
- }
336
- // Post Process Entities because there's some special handling of the sub-objects
337
- simpleMetadata.AllEntities = this.PostProcessEntityMetadata(simpleMetadata.Entities, simpleMetadata.EntityFields, simpleMetadata.EntityFieldValues, simpleMetadata.EntityPermissions, simpleMetadata.EntityRelationships, simpleMetadata.EntitySettings);
338
- // Post Process the Applications, because we want to handle the sub-objects properly.
339
- simpleMetadata.AllApplications = simpleMetadata.Applications.map((a) => {
340
- a.ApplicationEntities = simpleMetadata.ApplicationEntities.filter((ae) => ae.ApplicationID === a.ID);
341
- a.ApplicationSettings = simpleMetadata.ApplicationSettings.filter((as) => as.ApplicationID === a.ID);
342
- return new applicationInfo_1.ApplicationInfo(a, this);
343
- });
344
- // now we need to construct our return type. The way the return type works, which is an instance of AllMetadata, we have to
345
- // construst each item so it contains an array of the correct type. This is because the AllMetadata class has an array of each type of metadata
346
- // rather than just plain JavaScript objects that we have in the allMetadata object.
347
- // build the base return type
348
- const returnMetadata = MetadataFromSimpleObjectWithoutUser(simpleMetadata, this);
349
- returnMetadata.CurrentUser = await this.GetCurrentUser();
350
- return returnMetadata;
351
- }
352
- else {
353
- (0, logging_1.LogError)('GetAllMetadata() - Error getting metadata from server' + (d ? ': ' + d.Status : ''));
354
- }
355
- }
356
- catch (e) {
357
- (0, logging_1.LogError)(e);
358
- }
359
- }
360
- /**
361
- * Post-processes entity metadata to establish relationships between entities and their child objects.
362
- * Links fields, permissions, relationships, and settings to their parent entities.
363
- * @param entities - Array of entity metadata
364
- * @param fields - Array of entity field metadata
365
- * @param fieldValues - Array of entity field value metadata
366
- * @param permissions - Array of entity permission metadata
367
- * @param relationships - Array of entity relationship metadata
368
- * @param settings - Array of entity settings metadata
369
- * @returns Processed array of EntityInfo instances with all relationships established
370
- */
371
- PostProcessEntityMetadata(entities, fields, fieldValues, permissions, relationships, settings) {
372
- const result = [];
373
- if (fieldValues && fieldValues.length > 0)
374
- for (let f of fields) {
375
- // populate the field values for each field, if we have them
376
- f.EntityFieldValues = fieldValues.filter((fv) => fv.EntityFieldID === f.ID);
377
- }
378
- for (let e of entities) {
379
- e.EntityFields = fields.filter((f) => f.EntityID === e.ID).sort((a, b) => a.Sequence - b.Sequence);
380
- e.EntityPermissions = permissions.filter((p) => p.EntityID === e.ID);
381
- e.EntityRelationships = relationships.filter((r) => r.EntityID === e.ID);
382
- e.EntitySettings = settings.filter((s) => s.EntityID === e.ID);
383
- result.push(new entityInfo_1.EntityInfo(e));
384
- }
385
- return result;
386
- }
387
- /**
388
- * Gets the configuration data that was provided to the provider.
389
- * @returns The provider configuration including schema filters
390
- */
391
- get ConfigData() {
392
- return this._ConfigData;
393
- }
394
- /**
395
- * Gets all entity metadata in the system.
396
- * @returns Array of EntityInfo objects representing all entities
397
- */
398
- get Entities() {
399
- return this._localMetadata.AllEntities;
400
- }
401
- /**
402
- * Gets all application metadata in the system.
403
- * @returns Array of ApplicationInfo objects representing all applications
404
- */
405
- get Applications() {
406
- return this._localMetadata.AllApplications;
407
- }
408
- /**
409
- * Gets the current user's information including roles and permissions.
410
- * @returns UserInfo object for the authenticated user
411
- */
412
- get CurrentUser() {
413
- return this._localMetadata.CurrentUser;
414
- }
415
- /**
416
- * Gets all security roles defined in the system.
417
- * @returns Array of RoleInfo objects representing all roles
418
- */
419
- get Roles() {
420
- return this._localMetadata.AllRoles;
421
- }
422
- /**
423
- * Gets all row-level security filters defined in the system.
424
- * @returns Array of RowLevelSecurityFilterInfo objects for data access control
425
- */
426
- get RowLevelSecurityFilters() {
427
- return this._localMetadata.AllRowLevelSecurityFilters;
428
- }
429
- /**
430
- * Gets all audit log types defined for tracking system activities.
431
- * @returns Array of AuditLogTypeInfo objects
432
- */
433
- get AuditLogTypes() {
434
- return this._localMetadata.AllAuditLogTypes;
435
- }
436
- /**
437
- * Gets all authorization definitions in the system.
438
- * @returns Array of AuthorizationInfo objects defining permissions
439
- */
440
- get Authorizations() {
441
- return this._localMetadata.AllAuthorizations;
442
- }
443
- /**
444
- * Gets all saved queries in the system.
445
- * @returns Array of QueryInfo objects representing stored queries
446
- */
447
- get Queries() {
448
- return this._localMetadata.AllQueries;
449
- }
450
- /**
451
- * Gets all query category definitions.
452
- * @returns Array of QueryCategoryInfo objects for query organization
453
- */
454
- get QueryCategories() {
455
- return this._localMetadata.AllQueryCategories;
456
- }
457
- /**
458
- * Gets all query field definitions.
459
- * @returns Array of QueryFieldInfo objects defining query result columns
460
- */
461
- get QueryFields() {
462
- return this._localMetadata.AllQueryFields;
463
- }
464
- /**
465
- * Gets all query permission assignments.
466
- * @returns Array of QueryPermissionInfo objects defining query access
467
- */
468
- get QueryPermissions() {
469
- return this._localMetadata.AllQueryPermissions;
470
- }
471
- /**
472
- * Gets all query entity associations.
473
- * @returns Array of QueryEntityInfo objects linking queries to entities
474
- */
475
- get QueryEntities() {
476
- return this._localMetadata.AllQueryEntities;
477
- }
478
- /**
479
- * Gets all query parameter definitions.
480
- * @returns Array of QueryParameterInfo objects for parameterized queries
481
- */
482
- get QueryParameters() {
483
- return this._localMetadata.AllQueryParameters;
484
- }
485
- /**
486
- * Gets all library definitions in the system.
487
- * @returns Array of LibraryInfo objects representing code libraries
488
- */
489
- get Libraries() {
490
- return this._localMetadata.AllLibraries;
491
- }
492
- /**
493
- * Gets all explorer navigation items including inactive ones.
494
- * @returns Array of all ExplorerNavigationItem objects
495
- */
496
- get AllExplorerNavigationItems() {
497
- return this._localMetadata.AllExplorerNavigationItems;
498
- }
499
- /**
500
- * Gets only active explorer navigation items sorted by sequence.
501
- * Results are cached for performance.
502
- * @returns Array of active ExplorerNavigationItem objects
503
- */
504
- get VisibleExplorerNavigationItems() {
505
- // filter and sort once and cache
506
- if (!this._cachedVisibleExplorerNavigationItems)
507
- this._cachedVisibleExplorerNavigationItems = this._localMetadata.AllExplorerNavigationItems.filter((e) => e.IsActive).sort((a, b) => a.Sequence - b.Sequence);
508
- return this._cachedVisibleExplorerNavigationItems;
509
- }
510
- /**
511
- * Refreshes all metadata from the server.
512
- * Respects the AllowRefresh flag from subclasses.
513
- * @returns True if refresh was initiated or allowed
514
- */
515
- async Refresh(providerToUse) {
516
- // do nothing here, but set a _refresh flag for next time things are requested
517
- if (this.AllowRefresh) {
518
- this._refresh = true;
519
- return this.Config(this._ConfigData, providerToUse);
520
- }
521
- else
522
- return true; // subclass is telling us not to do any refresh ops right now
523
- }
524
- /**
525
- * Checks if local metadata is out of date and needs refreshing.
526
- * Compares local timestamps with server timestamps.
527
- * @returns True if refresh is needed, false otherwise
528
- */
529
- async CheckToSeeIfRefreshNeeded(providerToUse) {
530
- if (this.AllowRefresh) {
531
- await this.RefreshRemoteMetadataTimestamps(providerToUse); // get the latest timestamps from the server first
532
- await this.LoadLocalMetadataFromStorage(); // then, attempt to load before we check to see if it is obsolete
533
- return this.LocalMetadataObsolete();
534
- } //subclass is telling us not to do any refresh ops right now
535
- else
536
- return false;
537
- }
538
- /**
539
- * Refreshes metadata only if needed based on timestamp comparison.
540
- * Combines check and refresh into a single operation.
541
- * @returns True if refresh was successful or not needed
542
- */
543
- async RefreshIfNeeded(providerToUse) {
544
- if (await this.CheckToSeeIfRefreshNeeded(providerToUse))
545
- return this.Refresh(providerToUse);
546
- else
547
- return true;
548
- }
549
- async GetEntityObject(entityName, loadKeyOrContextUser, contextUser) {
550
- try {
551
- // Determine which overload was called
552
- let actualLoadKey;
553
- let actualContextUser;
554
- if (loadKeyOrContextUser instanceof compositeKey_1.CompositeKey) {
555
- // Second overload: entityName, loadKey, contextUser
556
- actualLoadKey = loadKeyOrContextUser;
557
- actualContextUser = contextUser;
558
- }
559
- else if (contextUser !== undefined) {
560
- // Second overload with null/undefined loadKey: entityName, null/undefined, contextUser
561
- actualLoadKey = undefined;
562
- actualContextUser = contextUser;
563
- }
564
- else {
565
- // First overload: entityName, contextUser
566
- actualContextUser = loadKeyOrContextUser;
567
- }
568
- const entity = this.Metadata.Entities.find((e) => e.Name == entityName);
569
- if (entity) {
570
- // Use the MJGlobal Class Factory to do our object instantiation - we do NOT use metadata for this anymore, doesn't work well to have file paths with node dynamically at runtime
571
- // type reference registration by any module via MJ Global is the way to go as it is reliable across all platforms.
572
- try {
573
- const newObject = Global_1.MJGlobal.Instance.ClassFactory.CreateInstance(baseEntity_1.BaseEntity, entityName, entity, this);
574
- await newObject.Config(actualContextUser);
575
- if (actualLoadKey) {
576
- // Load existing record
577
- const loadResult = await newObject.InnerLoad(actualLoadKey);
578
- if (!loadResult) {
579
- throw new Error(`Failed to load ${entityName} with key: ${actualLoadKey.ToString()}`);
580
- }
581
- }
582
- else {
583
- // whenever we create a new object we want it to start
584
- // out as a new record, so we call NewRecord() on it
585
- newObject.NewRecord();
586
- }
587
- return newObject;
588
- }
589
- catch (e) {
590
- (0, logging_1.LogError)(e);
591
- throw new Error(`Entity ${entityName} could not be instantiated via MJGlobal Class Factory. Make sure you have registered the class reference with MJGlobal.Instance.ClassFactory.Register(). ALSO, make sure you call LoadGeneratedEntities() from the GeneratedEntities project within your project as tree-shaking sometimes removes subclasses and could be causing this error!`);
592
- }
593
- }
594
- else
595
- throw new Error(`Entity ${entityName} not found in metadata`);
596
- }
597
- catch (ex) {
598
- (0, logging_1.LogError)(ex);
599
- return null;
600
- }
601
- }
602
- /**
603
- * Returns a list of entity dependencies, basically metadata that tells you the links to this entity from all other entities.
604
- * @param entityName
605
- * @returns
606
- */
607
- async GetEntityDependencies(entityName) {
608
- // using our metadata, find all of the foreign keys that point to this entity
609
- // go through each entity and find all the fields that have a RelatedEntity = entityName
610
- try {
611
- const eName = entityName.trim().toLowerCase();
612
- const result = [];
613
- for (let re of this.Entities) {
614
- const relatedFields = re.Fields.filter((f) => f.RelatedEntity?.trim().toLowerCase() === eName);
615
- // we now have all the fields, so let's create the EntityDependency objects
616
- relatedFields.map((f) => {
617
- result.push({
618
- EntityName: entityName,
619
- RelatedEntityName: re.Name,
620
- FieldName: f.Name,
621
- });
622
- });
623
- }
624
- return result;
625
- }
626
- catch (e) {
627
- (0, logging_1.LogError)(e);
628
- throw e;
629
- }
630
- }
631
- /**
632
- * Gets a database by name, if required, and caches it in a format available to the client (e.g. IndexedDB, LocalStorage, File, etc). The cache method is Provider specific
633
- * If itemFilters are provided, the combination of datasetName and the filters are used to determine a match in the cache
634
- * @param datasetName
635
- * @param itemFilters
636
- */
637
- async GetAndCacheDatasetByName(datasetName, itemFilters, contextUser, providerToUse) {
638
- // first see if we have anything in cache at all, no reason to check server dates if we dont
639
- if (await this.IsDatasetCached(datasetName, itemFilters)) {
640
- // compare the local version, if exists to the server version dates
641
- if (await this.IsDatasetCacheUpToDate(datasetName, itemFilters)) {
642
- // we're up to date, all we need to do is get the local cache and return it
643
- return this.GetCachedDataset(datasetName, itemFilters);
644
- }
645
- else {
646
- // we're out of date, so get the dataset from the server
647
- const dataset = await this.GetDatasetByName(datasetName, itemFilters, contextUser, providerToUse);
648
- // cache it
649
- await this.CacheDataset(datasetName, itemFilters, dataset);
650
- return dataset;
651
- }
652
- }
653
- else {
654
- // get the dataset from the server
655
- const dataset = await this.GetDatasetByName(datasetName, itemFilters, contextUser, providerToUse);
656
- // cache it
657
- await this.CacheDataset(datasetName, itemFilters, dataset);
658
- return dataset;
659
- }
660
- }
661
- /**
662
- * Returns the timestamp of the local cached version of a given datasetName or null if there is no local cache for the
663
- * specified dataset
664
- * @param datasetName the name of the dataset to check
665
- * @param itemFilters optional filters to apply to the dataset
666
- */
667
- async GetLocalDatasetTimestamp(datasetName, itemFilters) {
668
- const ls = this.LocalStorageProvider;
669
- if (ls) {
670
- const key = this.GetDatasetCacheKey(datasetName, itemFilters);
671
- const dateKey = key + '_date';
672
- const val = await ls.GetItem(dateKey);
673
- if (val) {
674
- return new Date(val);
675
- }
676
- }
677
- }
678
- /**
679
- * This routine checks to see if the local cache version of a given datasetName/itemFilters combination is up to date with the server or not
680
- * @param datasetName
681
- * @param itemFilters
682
- * @returns
683
- */
684
- async IsDatasetCacheUpToDate(datasetName, itemFilters) {
685
- const localDate = await this.GetLocalDatasetTimestamp(datasetName, itemFilters);
686
- if (localDate) {
687
- // we have a local cached timestamp, so compare it to the server timestamp
688
- const status = await this.GetDatasetStatusByName(datasetName, itemFilters);
689
- if (status) {
690
- const serverTimestamp = status.LatestUpdateDate.getTime();
691
- if (localDate.getTime() >= serverTimestamp) {
692
- // this situation means our local cache timestamp is >= the server timestamp, so we're most likely up to date
693
- // in this situation, the last thing we check is for each entity, if the rowcount is the same as the server, if it is, we're good
694
- // iterate through all of the entities and check the row counts
695
- const localDataset = await this.GetCachedDataset(datasetName, itemFilters);
696
- for (const eu of status.EntityUpdateDates) {
697
- const localEntity = localDataset.Results.find((e) => e.EntityID === eu.EntityID);
698
- if (!localEntity || localEntity.Results.length !== eu.RowCount) {
699
- // we either couldn't find the entity in the local cache or the row count is different, so we're out of date
700
- // the RowCount being different picks up on DELETED rows. The UpdatedAt check which is handled above would pick up
701
- // on any new rows or updated rows. This approach makes sure we detect deleted rows and refresh the cache.
702
- return false;
703
- }
704
- }
705
- // if we get here that means that the row counts are the same for all entities and we're up to date
706
- return true;
707
- }
708
- else {
709
- // our local cache timestamp is < the server timestamp, so we're out of date
710
- return false;
711
- }
712
- }
713
- else {
714
- // we couldn't get the server status, so we're out of date
715
- return false;
716
- }
717
- }
718
- else {
719
- // we don't have a local cache timestamp, so we're out of date
720
- return false;
721
- }
722
- }
723
- /**
724
- * This routine gets the local cached version of a given datasetName/itemFilters combination, it does NOT check the server status first and does not fall back on the server if there isn't a local cache version of this dataset/itemFilters combination
725
- * @param datasetName
726
- * @param itemFilters
727
- * @returns
728
- */
729
- async GetCachedDataset(datasetName, itemFilters) {
730
- const ls = this.LocalStorageProvider;
731
- if (ls) {
732
- const key = this.GetDatasetCacheKey(datasetName, itemFilters);
733
- const val = await ls.GetItem(key);
734
- if (val) {
735
- const dataset = JSON.parse(val);
736
- return dataset;
737
- }
738
- }
739
- }
740
- /**
741
- * Stores a dataset in the local cache. If itemFilters are provided, the combination of datasetName and the filters are used to build a key and determine a match in the cache
742
- * @param datasetName
743
- * @param itemFilters
744
- * @param dataset
745
- */
746
- async CacheDataset(datasetName, itemFilters, dataset) {
747
- const ls = this.LocalStorageProvider;
748
- if (ls) {
749
- const key = this.GetDatasetCacheKey(datasetName, itemFilters);
750
- const val = JSON.stringify(dataset);
751
- await ls.SetItem(key, val);
752
- const dateKey = key + '_date';
753
- const dateVal = dataset.LatestUpdateDate.toISOString();
754
- await ls.SetItem(dateKey, dateVal);
755
- }
756
- }
757
- /**
758
- * Determines if a given datasetName/itemFilters combination is cached locally or not
759
- * @param datasetName
760
- * @param itemFilters
761
- * @returns
762
- */
763
- async IsDatasetCached(datasetName, itemFilters) {
764
- const ls = this.LocalStorageProvider;
765
- if (ls) {
766
- const key = this.GetDatasetCacheKey(datasetName, itemFilters);
767
- const val = await ls.GetItem(key);
768
- return val !== null && val !== undefined;
769
- }
770
- }
771
- /**
772
- * Creates a unique key for the given datasetName and itemFilters combination coupled with the instance connection string to ensure uniqueness when 2+ connections exist
773
- * @param datasetName
774
- * @param itemFilters
775
- * @returns
776
- */
777
- GetDatasetCacheKey(datasetName, itemFilters) {
778
- return (this.LocalStoragePrefix +
779
- _a.localStorageRootKey +
780
- this.InstanceConnectionString +
781
- '__DATASET__' +
782
- datasetName +
783
- this.ConvertItemFiltersToUniqueKey(itemFilters));
784
- }
785
- /**
786
- * Converts dataset item filters into a unique string key for caching.
787
- * @param itemFilters - Array of filters to convert
788
- * @returns JSON-formatted string representing the filters
789
- */
790
- ConvertItemFiltersToUniqueKey(itemFilters) {
791
- if (itemFilters) {
792
- const key = '{' + itemFilters.map((f) => `"${f.ItemCode}":"${f.Filter}"`).join(',') + '}'; // this is a unique key for the item filters
793
- return key;
794
- }
795
- else
796
- return '';
797
- }
798
- /**
799
- * If the specified datasetName is cached, this method will clear the cache. If itemFilters are provided, the combination of datasetName and the filters are used to determine a match in the cache
800
- * @param datasetName
801
- * @param itemFilters
802
- */
803
- async ClearDatasetCache(datasetName, itemFilters) {
804
- const ls = this.LocalStorageProvider;
805
- if (ls) {
806
- const key = this.GetDatasetCacheKey(datasetName, itemFilters);
807
- await ls.Remove(key);
808
- const dateKey = key + '_date';
809
- await ls.Remove(dateKey);
810
- }
811
- }
812
- /**
813
- * Gets the latest metadata timestamps from the remote server.
814
- * Used to determine if local cache is out of date.
815
- * @returns Array of metadata timestamp information
816
- */
817
- get LatestRemoteMetadata() {
818
- return this._latestRemoteMetadataTimestamps;
819
- }
820
- /**
821
- * Gets the latest metadata timestamps from local cache.
822
- * Used for comparison with remote timestamps.
823
- * @returns Array of locally cached metadata timestamps
824
- */
825
- get LatestLocalMetadata() {
826
- return this._latestLocalMetadataTimestamps;
827
- }
828
- /**
829
- * Retrieves the latest metadata update timestamps from the server.
830
- * @returns Array of metadata update information
831
- */
832
- async GetLatestMetadataUpdates(providerToUse) {
833
- const f = this.BuildDatasetFilterFromConfig();
834
- const d = await this.GetDatasetStatusByName(_a._mjMetadataDatasetName, f.length > 0 ? f : null, this.CurrentUser, providerToUse);
835
- if (d && d.Success) {
836
- const ret = d.EntityUpdateDates.map((e) => {
837
- return {
838
- ID: e.EntityID,
839
- Type: e.EntityName,
840
- UpdatedAt: e.UpdateDate,
841
- RowCount: e.RowCount,
842
- };
843
- });
844
- // combine the entityupdate dates with a single top level entry for the dataset itself
845
- ret.push({
846
- ID: '',
847
- Type: 'All Entity Metadata',
848
- UpdatedAt: d.LatestUpdateDate,
849
- RowCount: d.EntityUpdateDates.reduce((a, b) => a + b.RowCount, 0),
850
- });
851
- return ret;
852
- }
853
- }
854
- /**
855
- * Refreshes the remote metadata timestamps from the server.
856
- * Updates the internal cache of remote timestamps.
857
- * @returns True if timestamps were successfully refreshed
858
- */
859
- async RefreshRemoteMetadataTimestamps(providerToUse) {
860
- const mdTimeStamps = await this.GetLatestMetadataUpdates(providerToUse);
861
- if (mdTimeStamps) {
862
- this._latestRemoteMetadataTimestamps = mdTimeStamps;
863
- return true;
864
- }
865
- else
866
- return false;
867
- }
868
- /**
869
- * Checks if local metadata is obsolete compared to remote metadata.
870
- * Compares timestamps and row counts to detect changes.
871
- * @param type - Optional specific metadata type to check
872
- * @returns True if local metadata is out of date
873
- */
874
- LocalMetadataObsolete(type) {
875
- const mdLocal = this.LatestLocalMetadata;
876
- const mdRemote = this.LatestRemoteMetadata;
877
- if (!mdLocal || !mdRemote || !mdLocal.length || !mdRemote.length || mdLocal.length === 0 || mdRemote.length === 0)
878
- return true;
879
- for (let i = 0; i < mdRemote.length; ++i) {
880
- let bProcess = true;
881
- if (type && type.length > 0)
882
- bProcess = mdRemote[i].Type.toLowerCase().trim() === type.trim().toLowerCase();
883
- if (bProcess) {
884
- const l = mdLocal.find((md) => md.Type.trim().toLowerCase() === mdRemote[i].Type.trim().toLowerCase());
885
- if (!l)
886
- return true; // no match, obsolete in this case
887
- else {
888
- // we have a match, now test various things
889
- if (!l.UpdatedAt && !mdRemote[i].UpdatedAt) {
890
- // both are null, so we're good
891
- // do nothing, keep on truckin'
892
- // console.log('TEST: both are null, so we\'re good')
893
- }
894
- else if (l.UpdatedAt && mdRemote[i].UpdatedAt) {
895
- // both are not null, so we need to compare them
896
- const localTime = new Date(l.UpdatedAt);
897
- const remoteTime = new Date(mdRemote[i].UpdatedAt);
898
- if (localTime.getTime() !== remoteTime.getTime()) {
899
- return true; // we can short circuit the entire rest of the function
900
- // as one obsolete is good enough to obsolete the entire local metadata
901
- }
902
- else {
903
- // here we have a match for the local and remote timestamps, so we need to check the row counts
904
- // if the row counts are different, we're obsolete
905
- if (l.RowCount !== mdRemote[i].RowCount) {
906
- return true;
907
- }
908
- }
909
- }
910
- else
911
- return true; // one is null and the other is not, so we're obsolete without even comparing
912
- }
913
- }
914
- }
915
- // if we get here, we're not obsolete!!
916
- return false;
917
- }
918
- /**
919
- * Updates the local metadata cache with new data.
920
- * @param res - The new metadata to store locally
921
- */
922
- UpdateLocalMetadata(res) {
923
- this._localMetadata = res;
924
- }
925
- /**
926
- * Loads metadata from local storage if available.
927
- * Deserializes and reconstructs typed metadata objects.
928
- */
929
- async LoadLocalMetadataFromStorage() {
930
- try {
931
- const ls = this.LocalStorageProvider;
932
- if (ls) {
933
- // execution environment supports local storage, use it
934
- this._latestLocalMetadataTimestamps = JSON.parse(await ls.GetItem(this.LocalStoragePrefix + _a.localStorageTimestampsKey));
935
- const temp = JSON.parse(await ls.GetItem(this.LocalStoragePrefix + _a.localStorageAllMetadataKey)); // we now have a simple object for all the metadata
936
- if (temp) {
937
- // we have local metadata
938
- (0, logging_1.LogStatus)('Metadata loaded from local storage');
939
- const metadata = MetadataFromSimpleObject(temp, this); // create a new object to start this up
940
- this.UpdateLocalMetadata(metadata);
941
- }
942
- }
943
- }
944
- catch (e) {
945
- // some enviroments don't support local storage
946
- }
947
- }
948
- /**
949
- * This property will return the prefix to use for local storage keys. This is useful if you have multiple instances of a provider running in the same environment
950
- * and you want to keep their local storage keys separate. The default implementation returns an empty string, but subclasses can override this to return a unique string
951
- * based on the connection or other distinct identifier.
952
- */
953
- get LocalStoragePrefix() {
954
- return '';
955
- }
956
- /**
957
- * Saves current metadata to local storage for caching.
958
- * Serializes both timestamps and full metadata collections.
959
- */
960
- async SaveLocalMetadataToStorage() {
961
- try {
962
- const ls = this.LocalStorageProvider;
963
- if (ls) {
964
- // execution environment supports local storage, use it
965
- await ls.SetItem(this.LocalStoragePrefix + _a.localStorageTimestampsKey, JSON.stringify(this._latestLocalMetadataTimestamps));
966
- // now persist the AllMetadata object
967
- await ls.SetItem(this.LocalStoragePrefix + _a.localStorageAllMetadataKey, JSON.stringify(this._localMetadata));
968
- }
969
- }
970
- catch (e) {
971
- // some enviroments don't support local storage
972
- (0, logging_1.LogError)(e);
973
- }
974
- }
975
- /**
976
- * Removes all cached metadata from local storage.
977
- * Clears both timestamps and metadata collections.
978
- */
979
- async RemoveLocalMetadataFromStorage() {
980
- try {
981
- const ls = this.LocalStorageProvider;
982
- for (let i = 0; i < _a.localStorageKeys.length; i++) {
983
- await ls.Remove(this.LocalStoragePrefix + _a.localStorageKeys[i]);
984
- }
985
- }
986
- catch (e) {
987
- // some enviroments don't support local storage
988
- (0, logging_1.LogError)(e);
989
- }
990
- }
991
- }
992
- exports.ProviderBase = ProviderBase;
993
- _a = ProviderBase;
994
- ProviderBase._mjMetadataDatasetName = 'MJ_Metadata';
995
- ProviderBase.localStorageRootKey = '___MJCore_Metadata';
996
- ProviderBase.localStorageTimestampsKey = _a.localStorageRootKey + '_Timestamps';
997
- ProviderBase.localStorageAllMetadataKey = _a.localStorageRootKey + '_AllMetadata';
998
- ProviderBase.localStorageKeys = [_a.localStorageTimestampsKey, _a.localStorageAllMetadataKey];
999
- //# sourceMappingURL=providerBase.js.map