@ianua/ianus-dataverse-react-fluentui8 1.0.5 → 1.0.8

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 CHANGED
@@ -16,11 +16,10 @@ interface ILicenseClaims {
16
16
  prd: string;
17
17
  sub: string;
18
18
  env: IEnvironmentIdentifier[];
19
- required_roles: string[];
20
19
  iat: number;
21
20
  nbf: number;
22
21
  exp?: number;
23
- custom: Record<string, any>;
22
+ cus: Record<string, any>;
24
23
  iss_meta: IMeta;
25
24
  aud_meta: IMeta;
26
25
  pub_meta: IMeta;
@@ -56,13 +55,48 @@ type LicenseValidationSuccess = {
56
55
  };
57
56
  type LicenseValidationResult = LicenseValidationError | LicenseValidationSuccess;
58
57
 
58
+ type EnvironmentType = "entra" | "dataverse";
59
59
  interface IIanusGuardProps {
60
+ /**
61
+ * The external publisher Guid found on the publisher's Ianus Guard portal form
62
+ */
60
63
  publisherId: string;
64
+ /**
65
+ * The external product Guid found on the product's Ianus Guard portal form
66
+ */
61
67
  productId: string;
68
+ /**
69
+ * One or multiple public keys, found on the product's Ianus Guard portal form or your own generated public key
70
+ */
62
71
  publicKeys: string[];
63
- environmentType: string;
72
+ /**
73
+ * Type of environment you're currently evaluating against
74
+ */
75
+ environmentType: EnvironmentType;
76
+ /**
77
+ * Identifier for the current environment. For entra this is the Tenant ID, for dataverse this is the Organization ID. For dataverse you can pass the WebApi object to fetch it automatically
78
+ */
64
79
  environmentIdentifier: string | ComponentFramework.WebApi;
80
+ /**
81
+ * Data provider for retrieving licenses in the current environment. Either a dataset or the WebApi object
82
+ */
65
83
  dataProvider: ComponentFramework.WebApi | ComponentFramework.PropertyTypes.DataSet;
84
+ /**
85
+ * Data provider for retrieving licenses in the current environment. Only needed in canvas apps. PCFs can query offline data using the primary (webAPI) data provider.
86
+ */
87
+ offlineDataProvider?: ComponentFramework.PropertyTypes.DataSet;
88
+ /**
89
+ * When using user-based licensing, usage permission is derived by having read permission to a defined 'usage-entity'. Pass the result of the license check here, if read is allowed, pass true, otherwise false.
90
+ * Pass null while you're fetching the permission.
91
+ * For canvas apps, use the DataSourceInfo PowerFX function, for PCFs use pcfContext.utils.getEntityMetadata for loading the metadata followed by pcfContext.utils.hasEntityPrivilege for getting the permission result.
92
+ */
93
+ usagePermission?: boolean | null;
94
+ /**
95
+ * Optionally pass a callback which is called when a license validation result was generated
96
+ *
97
+ * @param result The result of this validation run
98
+ * @returns Returned data will not be processed in any way
99
+ */
66
100
  onLicenseValidated?: (result: LicenseValidationResult) => unknown;
67
101
  }
68
102
  declare const isWebApi: (dataProvider: ComponentFramework.WebApi | ComponentFramework.PropertyTypes.DataSet | string) => dataProvider is ComponentFramework.WebApi;
@@ -96,6 +130,7 @@ interface ILicenseDialogProps {
96
130
  publisherId: string;
97
131
  productId: string;
98
132
  dataProvider: ComponentFramework.WebApi | ComponentFramework.PropertyTypes.DataSet;
133
+ offlineDataProvider?: ComponentFramework.PropertyTypes.DataSet;
99
134
  onSubmit: () => void;
100
135
  onCancel: () => void;
101
136
  }
@@ -106,4 +141,4 @@ declare const removeCurlyBrackets: (input: string | undefined | null) => string
106
141
  declare const base64url_decode: (value: string) => ArrayBuffer;
107
142
  declare const validateLicense: (publisherId: string, productId: string, environmentType: string, environmentIdentifier: string, publicKeys: string[], licenseKey: string | undefined) => Promise<LicenseValidationResult>;
108
143
 
109
- export { type DataverseLicenseValidationError, type DataverseLicenseValidationResult, type DataverseLicenseValidationSuccess, type IEnvironmentIdentifier, type IIanusGuardProps, type IIanusProviderProps, type ILicenseClaims, type ILicenseDialogProps, type IMeta, IanusGuard, IanusLicenseDispatch, type IanusLicenseStateProps, IanusLicenseStateProvider, IanusProvider, LicenseDialog, type LicenseValidationError, type LicenseValidationResult, type LicenseValidationSuccess, acquireLicenses, base64url_decode, isDataset, isWebApi, removeCurlyBrackets, useLicenseContext, useLicenseDispatch, useLicenseState, validateLicense };
144
+ export { type DataverseLicenseValidationError, type DataverseLicenseValidationResult, type DataverseLicenseValidationSuccess, type EnvironmentType, type IEnvironmentIdentifier, type IIanusGuardProps, type IIanusProviderProps, type ILicenseClaims, type ILicenseDialogProps, type IMeta, IanusGuard, IanusLicenseDispatch, type IanusLicenseStateProps, IanusLicenseStateProvider, IanusProvider, LicenseDialog, type LicenseValidationError, type LicenseValidationResult, type LicenseValidationSuccess, acquireLicenses, base64url_decode, isDataset, isWebApi, removeCurlyBrackets, useLicenseContext, useLicenseDispatch, useLicenseState, validateLicense };
package/dist/index.js CHANGED
@@ -65,8 +65,8 @@ var __async = (__this, __arguments, generator) => {
65
65
  };
66
66
 
67
67
  // src/index.ts
68
- var src_exports = {};
69
- __export(src_exports, {
68
+ var index_exports = {};
69
+ __export(index_exports, {
70
70
  IanusGuard: () => IanusGuard,
71
71
  IanusLicenseStateProvider: () => IanusLicenseStateProvider,
72
72
  IanusProvider: () => IanusProvider,
@@ -81,7 +81,7 @@ __export(src_exports, {
81
81
  useLicenseState: () => useLicenseState,
82
82
  validateLicense: () => validateLicense
83
83
  });
84
- module.exports = __toCommonJS(src_exports);
84
+ module.exports = __toCommonJS(index_exports);
85
85
 
86
86
  // src/IanusGuard.tsx
87
87
  var React3 = __toESM(require("react"));
@@ -154,7 +154,7 @@ var base64url_decode = (value) => {
154
154
  value.replace(/-/g, "+").replace(/_/g, "/").padEnd(value.length + (m === 0 ? 0 : 4 - m), "=")
155
155
  ), (c) => c.charCodeAt(0)).buffer;
156
156
  };
157
- var verifySignature = (key, dataToVerify, signature) => __async(void 0, null, function* () {
157
+ var verifySignature = (key, dataToVerify, signature) => __async(null, null, function* () {
158
158
  return yield window.crypto.subtle.verify(
159
159
  "RSASSA-PKCS1-v1_5",
160
160
  key,
@@ -162,7 +162,7 @@ var verifySignature = (key, dataToVerify, signature) => __async(void 0, null, fu
162
162
  dataToVerify
163
163
  );
164
164
  });
165
- var validateLicense = (publisherId, productId, environmentType, environmentIdentifier, publicKeys, licenseKey) => __async(void 0, null, function* () {
165
+ var validateLicense = (publisherId, productId, environmentType, environmentIdentifier, publicKeys, licenseKey) => __async(null, null, function* () {
166
166
  if (!licenseKey) {
167
167
  return {
168
168
  isValid: false,
@@ -277,23 +277,25 @@ var dialogContentProps = {
277
277
  type: import_react.DialogType.largeHeader,
278
278
  title: "License"
279
279
  };
280
- var LicenseDialog = ({ publisherId, productId, dataProvider, onCancel, onSubmit }) => {
281
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
280
+ var LicenseDialog = ({ publisherId, productId, dataProvider, offlineDataProvider, onCancel, onSubmit }) => {
281
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
282
282
  const [licenseState, licenseDispatch] = useLicenseContext();
283
283
  const [submitBlocked, setSubmitBlocked] = React2.useState(true);
284
284
  const [licenseKeyInput, setLicenseKeyInput] = React2.useState((_a = licenseState.license) == null ? void 0 : _a.licenseKey);
285
285
  const [licenseId, setLicenseId] = React2.useState((_b = licenseState == null ? void 0 : licenseState.license) == null ? void 0 : _b.licenseId);
286
286
  const [error, setError] = React2.useState("");
287
287
  React2.useEffect(() => {
288
- (() => __async(void 0, null, function* () {
288
+ (() => __async(null, null, function* () {
289
289
  if (!licenseId) {
290
- const licenses = yield acquireLicenses(publisherId, productId, dataProvider);
290
+ const onlineLicenses = yield acquireLicenses(publisherId, productId, dataProvider);
291
+ const offlineLicenses = offlineDataProvider != null ? yield acquireLicenses(publisherId, productId, offlineDataProvider) : [];
292
+ const licenses = onlineLicenses.length ? onlineLicenses : offlineLicenses;
291
293
  if (licenses.length > 0) {
292
294
  setLicenseId(licenses[0].ian_licenseid);
293
295
  }
294
296
  }
295
297
  }))();
296
- }, []);
298
+ }, [dataProvider, licenseId, offlineDataProvider, productId, publisherId]);
297
299
  const tryToExtractDisplayNames = (licenseKey) => {
298
300
  var _a2, _b2;
299
301
  if (!licenseKey) {
@@ -319,8 +321,8 @@ var LicenseDialog = ({ publisherId, productId, dataProvider, onCancel, onSubmit
319
321
  return null;
320
322
  }
321
323
  };
322
- const onSubmitClick = () => __async(void 0, null, function* () {
323
- var _a2, _b2;
324
+ const onSubmitClick = () => __async(null, null, function* () {
325
+ var _a2, _b2, _c2;
324
326
  try {
325
327
  setSubmitBlocked(true);
326
328
  const displayNames = tryToExtractDisplayNames(licenseKeyInput);
@@ -337,9 +339,19 @@ var LicenseDialog = ({ publisherId, productId, dataProvider, onCancel, onSubmit
337
339
  }
338
340
  );
339
341
  } else if (isDataset(dataProvider)) {
340
- yield dataProvider.records[licenseId].setValue("ian_name", name);
341
- yield dataProvider.records[licenseId].setValue("ian_key", licenseKeyInput);
342
- yield dataProvider.records[licenseId].save();
342
+ if (dataProvider.records[licenseId]) {
343
+ yield dataProvider.records[licenseId].setValue("ian_name", name);
344
+ yield dataProvider.records[licenseId].setValue("ian_key", licenseKeyInput);
345
+ yield dataProvider.records[licenseId].save();
346
+ dataProvider.refresh();
347
+ } else {
348
+ const newLicense = yield dataProvider.newRecord();
349
+ yield newLicense.setValue("ian_name", name);
350
+ yield newLicense.setValue("ian_identifier", identifier);
351
+ yield newLicense.setValue("ian_key", licenseKeyInput);
352
+ yield newLicense.save();
353
+ dataProvider.refresh();
354
+ }
343
355
  }
344
356
  } else {
345
357
  if (isWebApi(dataProvider)) {
@@ -357,11 +369,12 @@ var LicenseDialog = ({ publisherId, productId, dataProvider, onCancel, onSubmit
357
369
  yield newLicense.setValue("ian_identifier", identifier);
358
370
  yield newLicense.setValue("ian_key", licenseKeyInput);
359
371
  yield newLicense.save();
372
+ dataProvider.refresh();
360
373
  }
361
374
  }
362
375
  onSubmit();
363
376
  } catch (e) {
364
- setError(e == null ? void 0 : e.message);
377
+ setError((_c2 = e == null ? void 0 : e.message) != null ? _c2 : JSON.stringify(e));
365
378
  } finally {
366
379
  setSubmitBlocked(false);
367
380
  }
@@ -391,31 +404,34 @@ var LicenseDialog = ({ publisherId, productId, dataProvider, onCancel, onSubmit
391
404
  setLicenseKeyInput(v != null ? v : "");
392
405
  setSubmitBlocked(false);
393
406
  }, required: true }),
394
- !!((_c = licenseState.license) == null ? void 0 : _c.isValid) && /* @__PURE__ */ React2.createElement(import_react.Text, null, /* @__PURE__ */ React2.createElement("br", null), /* @__PURE__ */ React2.createElement("h3", null, "License Information"), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "License Publisher: "), " ", /* @__PURE__ */ React2.createElement("span", { title: (_e = (_d = licenseState.license) == null ? void 0 : _d.claims) == null ? void 0 : _e.pub }, (_h = (_g = (_f = licenseState.license) == null ? void 0 : _f.claims) == null ? void 0 : _g.pub_meta) == null ? void 0 : _h.name)), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Licensed Product: "), " ", /* @__PURE__ */ React2.createElement("span", { title: (_i = licenseState.license) == null ? void 0 : _i.claims.aud }, (_l = (_k = (_j = licenseState.license) == null ? void 0 : _j.claims) == null ? void 0 : _k.prd_meta) == null ? void 0 : _l.name)), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Licensed Customer: "), " ", /* @__PURE__ */ React2.createElement("span", { title: (_m = licenseState.license) == null ? void 0 : _m.claims.sub }, (_p = (_o = (_n = licenseState.license) == null ? void 0 : _n.claims) == null ? void 0 : _o.sub_meta) == null ? void 0 : _p.name)), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Licensed Dataverse Environment: "), " ", /* @__PURE__ */ React2.createElement("span", null, (_s = (_r = (_q = licenseState.license) == null ? void 0 : _q.claims) == null ? void 0 : _r.env) == null ? void 0 : _s.map((e) => `${e.identifier} (${e.name})`).join(", "))), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "License expires after: "), " ", /* @__PURE__ */ React2.createElement("span", null, !((_u = (_t = licenseState.license) == null ? void 0 : _t.claims) == null ? void 0 : _u.exp) ? "Never" : new Date(((_v = licenseState.license) == null ? void 0 : _v.claims.exp) * 1e3).toISOString()))),
407
+ !!((_c = licenseState.license) == null ? void 0 : _c.isValid) && /* @__PURE__ */ React2.createElement(import_react.Text, null, /* @__PURE__ */ React2.createElement("br", null), /* @__PURE__ */ React2.createElement("h3", null, "License Information"), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "License Publisher: "), " ", /* @__PURE__ */ React2.createElement("span", { title: (_e = (_d = licenseState.license) == null ? void 0 : _d.claims) == null ? void 0 : _e.pub }, (_h = (_g = (_f = licenseState.license) == null ? void 0 : _f.claims) == null ? void 0 : _g.pub_meta) == null ? void 0 : _h.name)), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Licensed Product: "), " ", /* @__PURE__ */ React2.createElement("span", { title: (_i = licenseState.license) == null ? void 0 : _i.claims.aud }, (_l = (_k = (_j = licenseState.license) == null ? void 0 : _j.claims) == null ? void 0 : _k.prd_meta) == null ? void 0 : _l.name)), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Licensed Customer: "), " ", /* @__PURE__ */ React2.createElement("span", { title: (_m = licenseState.license) == null ? void 0 : _m.claims.sub }, (_p = (_o = (_n = licenseState.license) == null ? void 0 : _n.claims) == null ? void 0 : _o.sub_meta) == null ? void 0 : _p.name)), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Licensed Dataverse Environment: "), " ", /* @__PURE__ */ React2.createElement("span", null, (_s = (_r = (_q = licenseState.license) == null ? void 0 : _q.claims) == null ? void 0 : _r.env) == null ? void 0 : _s.map((e) => `${e.identifier} (${e.name})`).join(", "))), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "License expires after: "), " ", /* @__PURE__ */ React2.createElement("span", null, !((_u = (_t = licenseState.license) == null ? void 0 : _t.claims) == null ? void 0 : _u.exp) ? "Never" : new Date(((_v = licenseState.license) == null ? void 0 : _v.claims.exp) * 1e3).toISOString())), ((_x = (_w = licenseState.license) == null ? void 0 : _w.claims) == null ? void 0 : _x.cus) && /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement("span", { style: { fontWeight: "bold" } }, "Custom claims: "), " ", /* @__PURE__ */ React2.createElement("span", null, JSON.stringify(licenseState.license.claims.cus)))),
395
408
  /* @__PURE__ */ React2.createElement(import_react.DialogFooter, null, /* @__PURE__ */ React2.createElement(import_react.PrimaryButton, { onClick: onSubmitClick, text: "Submit", disabled: !licenseKeyInput || submitBlocked }), /* @__PURE__ */ React2.createElement(import_react.DefaultButton, { onClick: onCancel, text: "Cancel" }))
396
409
  );
397
410
  };
398
411
 
399
412
  // src/IanusGuard.tsx
400
413
  var isWebApi = (dataProvider) => {
401
- return dataProvider.retrieveMultipleRecords !== void 0;
414
+ return (dataProvider == null ? void 0 : dataProvider.retrieveMultipleRecords) !== void 0;
402
415
  };
403
416
  var isDataset = (dataProvider) => {
404
- return dataProvider.records !== void 0;
417
+ return (dataProvider == null ? void 0 : dataProvider.sortedRecordIds) !== void 0;
405
418
  };
406
- var acquireLicenses = (publisherId, productId, dataProvider) => __async(void 0, null, function* () {
419
+ var acquireLicenses = (publisherId, productId, dataProvider) => __async(null, null, function* () {
420
+ var _a;
407
421
  const licenseIdentifier = `${publisherId}_${productId}`;
408
422
  if (isWebApi(dataProvider)) {
409
423
  const response = yield dataProvider.retrieveMultipleRecords("ian_license", `?$filter=ian_identifier eq '${licenseIdentifier}' and statecode eq 0`);
410
424
  return response.entities;
411
425
  } else if (isDataset(dataProvider)) {
412
- if (dataProvider.records.length) {
413
- const record = dataProvider.records[0];
414
- if (record.getNamedReference().etn !== "ian_license") {
426
+ const recordValues = Object.values((_a = dataProvider.records) != null ? _a : {});
427
+ if (recordValues.length) {
428
+ const record = recordValues[0];
429
+ const recordReference = record.getNamedReference();
430
+ if (recordReference.etn && recordReference.etn !== "ian_license") {
415
431
  throw new Error("You need to pass the 'ian_license' entity as data source for LicenseDataset when using a dataset as value");
416
432
  }
417
433
  }
418
- return Object.values(dataProvider.records).filter((r) => r.getValue("ian_identifier") === licenseIdentifier).map((r) => dataProvider.columns.reduce((all, cur) => __spreadProps(__spreadValues({}, all), { [cur.name]: r.getValue(cur.name) }), { ian_licenseid: r.getRecordId() }));
434
+ return recordValues.filter((r) => r.getValue("ian_identifier") === licenseIdentifier).map((r) => ({ ian_licenseid: r.getValue("ian_licenseid"), ian_identifier: r.getValue("ian_identifier"), ian_key: r.getValue("ian_key") }));
419
435
  } else {
420
436
  throw new Error(`The 'dataProvider' prop must be either of type ComponentFramework.WebApi or ComponentFramework.PropertyTypes.Dataset. You passed '${typeof dataProvider}'.`);
421
437
  }
@@ -431,7 +447,7 @@ var updateResultIfDefined = (result, onLicenseValidated) => {
431
447
  }
432
448
  }
433
449
  };
434
- var fetchOrganizationIdFromWebApi = (webApi) => __async(void 0, null, function* () {
450
+ var fetchOrganizationIdFromWebApi = (webApi) => __async(null, null, function* () {
435
451
  const results = yield webApi.retrieveMultipleRecords("organization", "?$top=1&$select=organizationid");
436
452
  if (!results.entities.length) {
437
453
  return null;
@@ -439,14 +455,14 @@ var fetchOrganizationIdFromWebApi = (webApi) => __async(void 0, null, function*
439
455
  const organization = results.entities[0];
440
456
  return organization.organizationid;
441
457
  });
442
- var IanusGuard = ({ publisherId, productId, publicKeys, environmentType, environmentIdentifier, dataProvider, onLicenseValidated, children }) => {
458
+ var IanusGuard = ({ publisherId, productId, publicKeys, environmentType, environmentIdentifier, dataProvider, offlineDataProvider, usagePermission, onLicenseValidated, children }) => {
443
459
  var _a, _b, _c, _d;
444
460
  const [licenseState, licenseDispatch] = useLicenseContext();
445
461
  const onSettingsFinally = () => {
446
462
  licenseDispatch({ type: "setLicenseDialogVisible", payload: false });
447
463
  initLicenseValidation();
448
464
  };
449
- const runValidation = () => __async(void 0, null, function* () {
465
+ const runValidation = React3.useCallback(() => __async(null, null, function* () {
450
466
  try {
451
467
  if (!productId) {
452
468
  return {
@@ -462,7 +478,9 @@ var IanusGuard = ({ publisherId, productId, publicKeys, environmentType, environ
462
478
  reason: "No public key found, pass a valid public key as prop!"
463
479
  };
464
480
  }
465
- const licenses = yield acquireLicenses(publisherId, productId, dataProvider);
481
+ const onlineLicenses = yield acquireLicenses(publisherId, productId, dataProvider);
482
+ const offlineLicenses = offlineDataProvider != null ? yield acquireLicenses(publisherId, productId, offlineDataProvider) : [];
483
+ const licenses = onlineLicenses.length ? onlineLicenses : offlineLicenses;
466
484
  if (!licenses.length) {
467
485
  return {
468
486
  isValid: false,
@@ -474,7 +492,7 @@ var IanusGuard = ({ publisherId, productId, publicKeys, environmentType, environ
474
492
  return {
475
493
  isValid: false,
476
494
  isTerminalError: true,
477
- reason: `Multiple active licenses for '${publisherId}_${productId}' found, please make sure there is only one active license`
495
+ reason: `Multiple active licenses for '${publisherId}_${productId}' found, please make sure there is only one active license. If on mobile canvas app, check for data updates in the device status / connection dialog and then clear cache.`
478
496
  };
479
497
  }
480
498
  const licenseRecord = licenses[0];
@@ -491,14 +509,59 @@ var IanusGuard = ({ publisherId, productId, publicKeys, environmentType, environ
491
509
  reason: e == null ? void 0 : e.message
492
510
  };
493
511
  }
494
- });
495
- const initLicenseValidation = () => __async(void 0, null, function* () {
512
+ }), [dataProvider, environmentIdentifier, environmentType, offlineDataProvider, productId, publicKeys, publisherId]);
513
+ const initLicenseValidation = React3.useCallback(() => __async(null, null, function* () {
496
514
  const result = yield runValidation();
497
515
  licenseDispatch({ type: "setLicense", payload: result });
498
516
  updateResultIfDefined(result, onLicenseValidated);
499
- });
517
+ }), [licenseDispatch, onLicenseValidated, runValidation]);
518
+ const dataTotalResultCount = isDataset(dataProvider) ? dataProvider.paging.totalResultCount : void 0;
519
+ const dataIsLoading = isDataset(dataProvider) ? dataProvider.loading : void 0;
520
+ const dataHasError = isDataset(dataProvider) ? dataProvider.error : void 0;
521
+ const dataProviderState = React3.useMemo(() => {
522
+ if (!isDataset(dataProvider)) {
523
+ return "webapi";
524
+ } else {
525
+ return `dataset-${dataTotalResultCount}-${dataIsLoading}-${dataHasError}`;
526
+ }
527
+ }, [dataProvider, dataHasError, dataIsLoading, dataTotalResultCount]);
528
+ const offlineDataTotalResultCount = offlineDataProvider != null ? offlineDataProvider.paging.totalResultCount : void 0;
529
+ const offlineDataIsLoading = offlineDataProvider != null ? offlineDataProvider.loading : void 0;
530
+ const offlineDataHasError = offlineDataProvider != null ? offlineDataProvider.error : void 0;
531
+ const offlineDataProviderState = React3.useMemo(() => {
532
+ if (offlineDataProvider == null) {
533
+ return "unused";
534
+ } else {
535
+ return `dataset-${offlineDataTotalResultCount}-${offlineDataIsLoading}-${offlineDataHasError}`;
536
+ }
537
+ }, [offlineDataHasError, offlineDataIsLoading, offlineDataProvider, offlineDataTotalResultCount]);
538
+ const dataProviderSignature = React3.useMemo(() => {
539
+ if (isDataset(dataProvider) && dataProvider.records) {
540
+ return Object.values(dataProvider.records).map((r) => `${r.getRecordId()}-${r.getValue("ian_identifier")}-${r.getValue("ian_key")}`).join("|");
541
+ }
542
+ return "";
543
+ }, [dataProvider]);
544
+ const offlineDataProviderSignature = React3.useMemo(() => {
545
+ if (offlineDataProvider && offlineDataProvider.records) {
546
+ return Object.values(offlineDataProvider.records).map((r) => `${r.getRecordId()}-${r.getValue("ian_identifier")}-${r.getValue("ian_key")}`).join("|");
547
+ }
548
+ return "";
549
+ }, [offlineDataProvider]);
500
550
  React3.useEffect(() => {
501
- if (!isDataset(dataProvider) || !dataProvider.error && !dataProvider.loading && dataProvider.paging.totalResultCount >= 0) {
551
+ console.log(`Starting license evaluation at ${(/* @__PURE__ */ new Date()).toISOString()}`);
552
+ console.log(`DataProvider state: ${dataProviderState}`);
553
+ console.log(`DataProvider signature: ${dataProviderSignature}`);
554
+ console.log(`Offline DataProvider state: ${offlineDataProviderState}`);
555
+ console.log(`Offline DataProvider signature: ${offlineDataProviderSignature}`);
556
+ if (usagePermission != null && !usagePermission) {
557
+ const result = {
558
+ isValid: false,
559
+ isTerminalError: true,
560
+ reason: "Your user is not enabled for using this product"
561
+ };
562
+ licenseDispatch({ type: "setLicense", payload: result });
563
+ updateResultIfDefined(result, onLicenseValidated);
564
+ } else if (!isDataset(dataProvider) || !dataProvider.error && !dataProvider.loading && dataProvider.paging.totalResultCount >= 0 || offlineDataProvider != null && !offlineDataProvider.error && !offlineDataProvider.loading && offlineDataProvider.paging.totalResultCount >= 0) {
502
565
  initLicenseValidation();
503
566
  } else if (dataProvider.error) {
504
567
  const result = {
@@ -506,12 +569,11 @@ var IanusGuard = ({ publisherId, productId, publicKeys, environmentType, environ
506
569
  isTerminalError: true,
507
570
  reason: `Dataset error: ${dataProvider.errorMessage}`
508
571
  };
572
+ licenseDispatch({ type: "setLicense", payload: result });
509
573
  updateResultIfDefined(result, onLicenseValidated);
510
574
  }
511
- }, [
512
- isDataset(dataProvider) ? dataProvider.sortedRecordIds.length : dataProvider
513
- ]);
514
- return ((_a = licenseState.license) == null ? void 0 : _a.isValid) ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, licenseState.licenseDialogVisible && /* @__PURE__ */ React3.createElement(LicenseDialog, { publisherId, productId, dataProvider, onSubmit: onSettingsFinally, onCancel: onSettingsFinally }), children) : /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", width: "100%", height: "100%", flex: "1" } }, licenseState.licenseDialogVisible && /* @__PURE__ */ React3.createElement(LicenseDialog, { publisherId, productId, dataProvider, onSubmit: onSettingsFinally, onCancel: onSettingsFinally }), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1 } }, ((_b = licenseState.license) == null ? void 0 : _b.isValid) === false && /* @__PURE__ */ React3.createElement(
575
+ }, [dataProvider, dataProviderState, dataProviderSignature, initLicenseValidation, licenseDispatch, usagePermission, onLicenseValidated, offlineDataProvider, offlineDataProviderState, offlineDataProviderSignature]);
576
+ return ((_a = licenseState.license) == null ? void 0 : _a.isValid) ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, licenseState.licenseDialogVisible && /* @__PURE__ */ React3.createElement(LicenseDialog, { publisherId, productId, dataProvider, offlineDataProvider, onSubmit: onSettingsFinally, onCancel: onSettingsFinally }), children) : /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", width: "100%", height: "100%", flex: "1" } }, licenseState.licenseDialogVisible && /* @__PURE__ */ React3.createElement(LicenseDialog, { publisherId, productId, dataProvider, offlineDataProvider, onSubmit: onSettingsFinally, onCancel: onSettingsFinally }), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1 } }, ((_b = licenseState.license) == null ? void 0 : _b.isValid) === false && /* @__PURE__ */ React3.createElement(
515
577
  import_MessageBar.MessageBar,
516
578
  {
517
579
  messageBarType: import_MessageBar.MessageBarType.error,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ianua/ianus-dataverse-react-fluentui8",
3
- "version": "1.0.5",
3
+ "version": "1.0.8",
4
4
  "description": "Client-side validation for Ianus Guard licenses in Dataverse using react and FluentUi v8",
5
5
  "scripts": {
6
6
  "build": "tsup"
@@ -16,7 +16,8 @@
16
16
  "react-dom": "^16.8 || ^17 || ^18"
17
17
  },
18
18
  "dependencies": {
19
- "@fluentui/react": "8.29.0",
19
+ "@fluentui/react": "^8",
20
+ "eslint-plugin-react-hooks": "^5.2.0",
20
21
  "react": "^16.8 || ^17 || ^18",
21
22
  "react-dom": "^16.8 || ^17 || ^18"
22
23
  },