@topolo/sdk 0.4.7 → 0.4.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.cjs CHANGED
@@ -113,32 +113,32 @@ var TopoloHttpError = class extends TopoloSdkError {
113
113
 
114
114
  // src/services.generated.ts
115
115
  var SERVICES = {
116
- agent: "https://agent-api.topolo.app",
116
+ agent: "https://agent.topolo.app",
117
117
  auth: "https://auth.topolo.app",
118
118
  backup: "https://backup.topolo.app",
119
119
  books: "https://books.topolo.app",
120
120
  bugfix: "https://bugfix.topolo.app",
121
- bytes: "https://bytes-api.topolo.app",
121
+ bytes: "https://bytes.topolo.app",
122
122
  calendar: "https://calendar.topolo.app",
123
123
  capacity: "https://capacity.topolo.app",
124
124
  chat: "https://chat.topolo.app",
125
- commerce: "https://commerce-api.topolo.app",
125
+ commerce: "https://commerce.topolo.app",
126
126
  compose: "https://compose.topolo.app",
127
127
  consent: "https://consent.topolo.app",
128
- crm: "https://crm-api.topolo.app",
128
+ crm: "https://crm.topolo.app",
129
129
  developers: "https://developers.topolo.app",
130
130
  director: "https://director.topolo.app",
131
- feed: "https://feed-api.topolo.app",
131
+ feed: "https://feed.topolo.app",
132
132
  flow: "https://flow.topolo.app",
133
- forecast: "https://forecast-api.topolo.app",
133
+ forecast: "https://forecast.topolo.app",
134
134
  forms: "https://forms.topolo.app",
135
135
  home: "https://home.topolo.app",
136
136
  insights: "https://insights.topolo.app",
137
137
  inventory: "https://inventory.topolo.app",
138
- learn: "https://learn-api.topolo.app",
138
+ learn: "https://learn.topolo.app",
139
139
  localize: "https://localize.topolo.app",
140
- mail: "https://mail-api.topolo.app",
141
- mdm: "https://mdm-api.topolo.app",
140
+ mail: "https://mail.topolo.app",
141
+ mdm: "https://mdm.topolo.app",
142
142
  messages: "https://messages.topolo.app",
143
143
  nexus: "https://nexus-api.topolo.app",
144
144
  notify: "https://notify.topolo.app",
@@ -147,20 +147,19 @@ var SERVICES = {
147
147
  p2p: "https://p2p.topolo.app",
148
148
  pay: "https://pay.topolo.app",
149
149
  people: "https://people.topolo.app",
150
- pulse: "https://pulse.topolo.app",
151
150
  "quro.api": "https://api.ol0.me",
152
151
  "quro.redirect": "https://ol0.me",
153
- roadmapper: "https://roadmapper-api.topolo.app",
152
+ roadmapper: "https://roadmapper.topolo.app",
154
153
  sign: "https://sign.topolo.app",
155
- social_studio: "https://studio-api.topolo.app",
156
- socialize: "https://socialize-api.topolo.app",
154
+ social_studio: "https://studio.topolo.app",
155
+ socialize: "https://socialize.topolo.app",
157
156
  spaces: "https://spaces.topolo.app",
158
157
  status: "https://status.topolo.app",
159
158
  success: "https://success.topolo.app",
160
159
  support: "https://support.topolo.app",
161
160
  survey: "https://survey.topolo.app",
162
161
  voice: "https://voice.topolo.app",
163
- web: "https://web-api.topolo.app"
162
+ web: "https://web.topolo.app"
164
163
  };
165
164
 
166
165
  // src/applications.generated.ts
@@ -211,17 +210,15 @@ var APPLICATIONS = {
211
210
  "agent.topolo.app"
212
211
  ],
213
212
  "routes": [],
214
- "serviceId": null
213
+ "serviceId": "agent"
215
214
  },
216
215
  {
217
216
  "name": "topolo-agent-api",
218
217
  "kind": "worker",
219
- "apiUrl": "https://agent-api.topolo.app",
220
- "domains": [
221
- "agent-api.topolo.app"
222
- ],
218
+ "apiUrl": null,
219
+ "domains": [],
223
220
  "routes": [],
224
- "serviceId": "agent"
221
+ "serviceId": null
225
222
  }
226
223
  ]
227
224
  },
@@ -341,17 +338,15 @@ var APPLICATIONS = {
341
338
  "bytes.topolo.app"
342
339
  ],
343
340
  "routes": [],
344
- "serviceId": null
341
+ "serviceId": "bytes"
345
342
  },
346
343
  {
347
344
  "name": "topolo-bytes-api",
348
345
  "kind": "worker",
349
- "apiUrl": "https://bytes-api.topolo.app",
350
- "domains": [
351
- "bytes-api.topolo.app"
352
- ],
346
+ "apiUrl": null,
347
+ "domains": [],
353
348
  "routes": [],
354
- "serviceId": "bytes"
349
+ "serviceId": null
355
350
  }
356
351
  ]
357
352
  },
@@ -450,12 +445,10 @@ var APPLICATIONS = {
450
445
  {
451
446
  "name": "topolo-commerce-api",
452
447
  "kind": "worker",
453
- "apiUrl": "https://commerce-api.topolo.app",
454
- "domains": [
455
- "commerce-api.topolo.app"
456
- ],
448
+ "apiUrl": null,
449
+ "domains": [],
457
450
  "routes": [],
458
- "serviceId": "commerce"
451
+ "serviceId": null
459
452
  },
460
453
  {
461
454
  "name": "topolo-commerce-guest-web",
@@ -475,7 +468,7 @@ var APPLICATIONS = {
475
468
  "commerce.topolo.app"
476
469
  ],
477
470
  "routes": [],
478
- "serviceId": null
471
+ "serviceId": "commerce"
479
472
  },
480
473
  {
481
474
  "name": "topolo-commerce-station-web",
@@ -562,12 +555,10 @@ var APPLICATIONS = {
562
555
  {
563
556
  "name": "topolo-crm-api",
564
557
  "kind": "worker",
565
- "apiUrl": "https://crm-api.topolo.app",
566
- "domains": [
567
- "crm-api.topolo.app"
568
- ],
558
+ "apiUrl": null,
559
+ "domains": [],
569
560
  "routes": [],
570
- "serviceId": "crm"
561
+ "serviceId": null
571
562
  },
572
563
  {
573
564
  "name": "topolo-crm-app",
@@ -577,7 +568,7 @@ var APPLICATIONS = {
577
568
  "crm.topolo.app"
578
569
  ],
579
570
  "routes": [],
580
- "serviceId": null
571
+ "serviceId": "crm"
581
572
  }
582
573
  ]
583
574
  },
@@ -700,12 +691,10 @@ var APPLICATIONS = {
700
691
  {
701
692
  "name": "topolo-feed-api",
702
693
  "kind": "worker",
703
- "apiUrl": "https://feed-api.topolo.app",
704
- "domains": [
705
- "feed-api.topolo.app"
706
- ],
694
+ "apiUrl": null,
695
+ "domains": [],
707
696
  "routes": [],
708
- "serviceId": "feed"
697
+ "serviceId": null
709
698
  },
710
699
  {
711
700
  "name": "topolo-feed-web",
@@ -715,7 +704,7 @@ var APPLICATIONS = {
715
704
  "feed.topolo.app"
716
705
  ],
717
706
  "routes": [],
718
- "serviceId": null
707
+ "serviceId": "feed"
719
708
  }
720
709
  ]
721
710
  },
@@ -767,17 +756,15 @@ var APPLICATIONS = {
767
756
  "forecast.topolo.app"
768
757
  ],
769
758
  "routes": [],
770
- "serviceId": null
759
+ "serviceId": "forecast"
771
760
  },
772
761
  {
773
762
  "name": "topolo-forecast-api",
774
763
  "kind": "worker",
775
- "apiUrl": "https://forecast-api.topolo.app",
776
- "domains": [
777
- "forecast-api.topolo.app"
778
- ],
764
+ "apiUrl": null,
765
+ "domains": [],
779
766
  "routes": [],
780
- "serviceId": "forecast"
767
+ "serviceId": null
781
768
  }
782
769
  ]
783
770
  },
@@ -919,17 +906,15 @@ var APPLICATIONS = {
919
906
  "learn.topolo.app"
920
907
  ],
921
908
  "routes": [],
922
- "serviceId": null
909
+ "serviceId": "learn"
923
910
  },
924
911
  {
925
912
  "name": "topolo-learn-api",
926
913
  "kind": "worker",
927
- "apiUrl": "https://learn-api.topolo.app",
928
- "domains": [
929
- "learn-api.topolo.app"
930
- ],
914
+ "apiUrl": null,
915
+ "domains": [],
931
916
  "routes": [],
932
- "serviceId": "learn"
917
+ "serviceId": null
933
918
  }
934
919
  ]
935
920
  },
@@ -975,17 +960,15 @@ var APPLICATIONS = {
975
960
  "mail.topolo.app"
976
961
  ],
977
962
  "routes": [],
978
- "serviceId": null
963
+ "serviceId": "mail"
979
964
  },
980
965
  {
981
966
  "name": "topolo-mail-api",
982
967
  "kind": "worker",
983
- "apiUrl": "https://mail-api.topolo.app",
984
- "domains": [
985
- "mail-api.topolo.app"
986
- ],
968
+ "apiUrl": null,
969
+ "domains": [],
987
970
  "routes": [],
988
- "serviceId": "mail"
971
+ "serviceId": null
989
972
  }
990
973
  ]
991
974
  },
@@ -1002,12 +985,10 @@ var APPLICATIONS = {
1002
985
  {
1003
986
  "name": "topolo-mdm-api",
1004
987
  "kind": "worker",
1005
- "apiUrl": "https://mdm-api.topolo.app",
1006
- "domains": [
1007
- "mdm-api.topolo.app"
1008
- ],
988
+ "apiUrl": null,
989
+ "domains": [],
1009
990
  "routes": [],
1010
- "serviceId": "mdm"
991
+ "serviceId": null
1011
992
  },
1012
993
  {
1013
994
  "name": "topolo-mdm-console",
@@ -1017,7 +998,7 @@ var APPLICATIONS = {
1017
998
  "mdm.topolo.app"
1018
999
  ],
1019
1000
  "routes": [],
1020
- "serviceId": null
1001
+ "serviceId": "mdm"
1021
1002
  }
1022
1003
  ]
1023
1004
  },
@@ -1276,36 +1257,6 @@ var APPLICATIONS = {
1276
1257
  }
1277
1258
  ]
1278
1259
  },
1279
- "pulse": {
1280
- "id": "pulse",
1281
- "appDir": "TopoloPulse",
1282
- "name": "topolo-pulse",
1283
- "packageName": "topolo-pulse",
1284
- "productionUrl": "https://pulse.topolo.app",
1285
- "services": [
1286
- "pulse"
1287
- ],
1288
- "deployTargets": [
1289
- {
1290
- "name": "topolo-pulse",
1291
- "kind": "worker",
1292
- "apiUrl": "https://pulse.topolo.app",
1293
- "domains": [
1294
- "pulse.topolo.app"
1295
- ],
1296
- "routes": [],
1297
- "serviceId": "pulse"
1298
- },
1299
- {
1300
- "name": "topolo-pulse-api",
1301
- "kind": "worker",
1302
- "apiUrl": null,
1303
- "domains": [],
1304
- "routes": [],
1305
- "serviceId": null
1306
- }
1307
- ]
1308
- },
1309
1260
  "quro": {
1310
1261
  "id": "quro",
1311
1262
  "appDir": "TopoloQuro",
@@ -1371,17 +1322,15 @@ var APPLICATIONS = {
1371
1322
  "roadmapper.topolo.app"
1372
1323
  ],
1373
1324
  "routes": [],
1374
- "serviceId": null
1325
+ "serviceId": "roadmapper"
1375
1326
  },
1376
1327
  {
1377
1328
  "name": "topolo-roadmapper-api",
1378
1329
  "kind": "worker",
1379
- "apiUrl": "https://roadmapper-api.topolo.app",
1380
- "domains": [
1381
- "roadmapper-api.topolo.app"
1382
- ],
1330
+ "apiUrl": null,
1331
+ "domains": [],
1383
1332
  "routes": [],
1384
- "serviceId": "roadmapper"
1333
+ "serviceId": null
1385
1334
  }
1386
1335
  ]
1387
1336
  },
@@ -1433,17 +1382,15 @@ var APPLICATIONS = {
1433
1382
  "studio.topolo.app"
1434
1383
  ],
1435
1384
  "routes": [],
1436
- "serviceId": null
1385
+ "serviceId": "social_studio"
1437
1386
  },
1438
1387
  {
1439
1388
  "name": "topolo-social-studio-api",
1440
1389
  "kind": "worker",
1441
- "apiUrl": "https://studio-api.topolo.app",
1442
- "domains": [
1443
- "studio-api.topolo.app"
1444
- ],
1390
+ "apiUrl": null,
1391
+ "domains": [],
1445
1392
  "routes": [],
1446
- "serviceId": "social_studio"
1393
+ "serviceId": null
1447
1394
  },
1448
1395
  {
1449
1396
  "name": "topolo-social-studio-queue",
@@ -1473,17 +1420,15 @@ var APPLICATIONS = {
1473
1420
  "socialize.topolo.app"
1474
1421
  ],
1475
1422
  "routes": [],
1476
- "serviceId": null
1423
+ "serviceId": "socialize"
1477
1424
  },
1478
1425
  {
1479
1426
  "name": "topolo-socialize-api",
1480
1427
  "kind": "worker",
1481
- "apiUrl": "https://socialize-api.topolo.app",
1482
- "domains": [
1483
- "socialize-api.topolo.app"
1484
- ],
1428
+ "apiUrl": null,
1429
+ "domains": [],
1485
1430
  "routes": [],
1486
- "serviceId": "socialize"
1431
+ "serviceId": null
1487
1432
  },
1488
1433
  {
1489
1434
  "name": "topolo-socialize-scheduler",
@@ -1684,12 +1629,10 @@ var APPLICATIONS = {
1684
1629
  {
1685
1630
  "name": "topolo-web-api",
1686
1631
  "kind": "worker",
1687
- "apiUrl": "https://web-api.topolo.app",
1688
- "domains": [
1689
- "web-api.topolo.app"
1690
- ],
1632
+ "apiUrl": null,
1633
+ "domains": [],
1691
1634
  "routes": [],
1692
- "serviceId": "web"
1635
+ "serviceId": null
1693
1636
  },
1694
1637
  {
1695
1638
  "name": "topolo-web-runtime",
@@ -1712,7 +1655,7 @@ var APPLICATIONS = {
1712
1655
  "web.topolo.app"
1713
1656
  ],
1714
1657
  "routes": [],
1715
- "serviceId": null
1658
+ "serviceId": "web"
1716
1659
  }
1717
1660
  ]
1718
1661
  }
@@ -1775,16 +1718,20 @@ var APPLICATION_REQUIREMENTS = [
1775
1718
  summary: "Browser applications should feel like one platform and should not create isolated navigation or account surfaces.",
1776
1719
  appliesTo: ["browser"],
1777
1720
  evidence: [
1778
- "@topolo/ui-kit is used for the platform shell where the app has authenticated UI",
1779
- "The shared launcher/app switcher is reachable from authenticated app chrome",
1780
- "Account menu and sign-out behavior use TopoloAppShell or TopoloAccountMenu",
1721
+ "@topolo-io/app-shell is used for the platform shell where the app has authenticated UI",
1722
+ "@topolo-io/app-launcher keeps the shared launcher/app switcher reachable from authenticated app chrome",
1723
+ "Account menu and sign-out behavior use TopoloAppShell or the ui-kit TopoloAccountMenu primitive",
1724
+ "Repeated app body surfaces use shared TopoloAppLayout primitives instead of local stat cards, empty states, or status badges",
1725
+ "Local preview supports deterministic visual QA fixtures for overview, list, detail, settings, and empty/loading states",
1781
1726
  "Authenticated app body content stays inside the viewport on mobile and desktop widths"
1782
1727
  ],
1783
1728
  implementation: [
1784
- "Use TopoloAppShell for authenticated app layouts",
1785
- "Use TopoloAccountMenu when a partial-shell surface still needs account chrome",
1729
+ "Use @topolo-io/app-shell TopoloAppShell for authenticated app layouts",
1730
+ "Use the @topolo-io/ui-kit TopoloAccountMenu primitive when a partial-shell surface still needs account chrome",
1786
1731
  "Pass app-specific account actions as additive menu items instead of forking dropdowns",
1787
1732
  "Use shared design tokens and platform UI primitives before creating local equivalents",
1733
+ "Use TopoloAppMetricCard, TopoloAppEmptyState, TopoloAppStatusBadge, TopoloAppGrid, and TopoloAppSection for repeated app body patterns",
1734
+ "Keep visual QA fixtures available through visualQa=1 or __devpreview=1 so screenshot checks do not depend on live API state",
1788
1735
  "Keep mobile and desktop shell behavior aligned with the platform UI kit",
1789
1736
  "Constrain app-owned workspace wrappers with min-width: 0, width: auto, and viewport-aware max-width so shell padding cannot create page-level horizontal overflow"
1790
1737
  ]
@@ -2166,6 +2113,8 @@ function firstString(...values) {
2166
2113
  var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
2167
2114
  var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
2168
2115
  var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
2116
+ var TOPOLO_RESOURCE_TYPE_HEADER = "X-Topolo-Resource-Type";
2117
+ var TOPOLO_RESOURCE_ID_HEADER = "X-Topolo-Resource-ID";
2169
2118
  var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
2170
2119
  var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
2171
2120
  var CATALOG_CACHE_TTL_MS = 60 * 1e3;
@@ -2244,6 +2193,18 @@ var TopoloClient = class _TopoloClient {
2244
2193
  if (opts.headers) {
2245
2194
  for (const [k, v] of Object.entries(opts.headers)) headers.set(k, v);
2246
2195
  }
2196
+ if (opts.resource) {
2197
+ const resourceType = opts.resource.resourceType.trim();
2198
+ const resourceId = opts.resource.resourceId.trim();
2199
+ if (!resourceType || !resourceId) {
2200
+ throw new TopoloSdkError(
2201
+ "invalid_resource_context",
2202
+ "Both resource.resourceType and resource.resourceId are required when resource context is provided."
2203
+ );
2204
+ }
2205
+ headers.set(TOPOLO_RESOURCE_TYPE_HEADER, resourceType);
2206
+ headers.set(TOPOLO_RESOURCE_ID_HEADER, resourceId);
2207
+ }
2247
2208
  const controller = new AbortController();
2248
2209
  const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
2249
2210
  const signal = opts.signal ? mergeSignals(opts.signal, controller.signal) : controller.signal;
@@ -2426,6 +2387,11 @@ var TopoloClient = class _TopoloClient {
2426
2387
  const serviceId = typeof s.service_id === "string" ? s.service_id : typeof s.id === "string" ? s.id : null;
2427
2388
  if (!serviceId) continue;
2428
2389
  const permissions = Array.isArray(s.granted_permissions) ? s.granted_permissions.filter((permission) => typeof permission === "string" && permission.trim().length > 0) : [];
2390
+ const catalogApiKeyResources = normalizeApiKeyResourceMetadataList(
2391
+ s.api_key_resources ?? s.apiKeyResources
2392
+ );
2393
+ const apiKeyResource = normalizeApiKeyResourceMetadata(s.api_key_resource ?? s.apiKeyResource) ?? catalogApiKeyResources[0] ?? null;
2394
+ const apiKeyResources = catalogApiKeyResources.length > 0 ? catalogApiKeyResources : apiKeyResource ? [apiKeyResource] : [];
2429
2395
  entries.push({
2430
2396
  serviceId,
2431
2397
  slug: typeof s.app_slug === "string" ? s.app_slug : null,
@@ -2436,7 +2402,9 @@ var TopoloClient = class _TopoloClient {
2436
2402
  status: typeof s.status === "string" ? s.status : null,
2437
2403
  surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
2438
2404
  launchable: s.launchable === true,
2439
- permissions
2405
+ permissions,
2406
+ apiKeyResource,
2407
+ apiKeyResources
2440
2408
  });
2441
2409
  }
2442
2410
  this.serviceCatalogCache = {
@@ -2522,7 +2490,9 @@ var TopoloClient = class _TopoloClient {
2522
2490
  status: "bundled",
2523
2491
  surfaceKind: "application",
2524
2492
  launchable: Boolean(app.productionUrl),
2525
- permissions: []
2493
+ permissions: [],
2494
+ apiKeyResource: null,
2495
+ apiKeyResources: []
2526
2496
  }));
2527
2497
  }
2528
2498
  /**
@@ -2571,6 +2541,46 @@ function resolveConfiguredServiceId(slug, serviceIds) {
2571
2541
  }
2572
2542
  return null;
2573
2543
  }
2544
+ function normalizeApiKeyResourceMetadata(input) {
2545
+ if (!isRecord(input)) return null;
2546
+ const resourceType = readString(input.resourceType ?? input.resource_type);
2547
+ const label = readString(input.label);
2548
+ const emptyLabel = readString(input.emptyLabel ?? input.empty_label);
2549
+ const resourceConcept = readString(input.resourceConcept ?? input.resource_concept);
2550
+ const canonicalResourceType = readString(input.canonicalResourceType ?? input.canonical_resource_type);
2551
+ const defaultEntitlement = readString(input.defaultEntitlement ?? input.default_entitlement);
2552
+ const exceptionPolicy = readString(input.exceptionPolicy ?? input.exception_policy);
2553
+ if (!resourceType || !label || !emptyLabel || resourceConcept !== "workspace" || canonicalResourceType !== "workspace" || defaultEntitlement !== "enterprise" || exceptionPolicy !== "app_or_organization") {
2554
+ return null;
2555
+ }
2556
+ return {
2557
+ resourceType,
2558
+ label,
2559
+ emptyLabel,
2560
+ resourceConcept,
2561
+ canonicalResourceType,
2562
+ defaultEntitlement,
2563
+ exceptionPolicy
2564
+ };
2565
+ }
2566
+ function normalizeApiKeyResourceMetadataList(input) {
2567
+ if (!Array.isArray(input)) return [];
2568
+ const resources = [];
2569
+ const seenTypes = /* @__PURE__ */ new Set();
2570
+ for (const item of input) {
2571
+ const resource = normalizeApiKeyResourceMetadata(item);
2572
+ if (!resource || seenTypes.has(resource.resourceType)) continue;
2573
+ seenTypes.add(resource.resourceType);
2574
+ resources.push(resource);
2575
+ }
2576
+ return resources;
2577
+ }
2578
+ function readString(value) {
2579
+ return typeof value === "string" ? value.trim() : "";
2580
+ }
2581
+ function isRecord(value) {
2582
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2583
+ }
2574
2584
  function resolveConfiguredServiceUrl(slug, serviceUrls) {
2575
2585
  for (const serviceKey of serviceKeyCandidates2(slug)) {
2576
2586
  const configured = serviceUrls?.[serviceKey];
@@ -3138,7 +3148,7 @@ function createTopoloWidgetError(error) {
3138
3148
  }
3139
3149
  function validateTopoloWidgetResponse(response) {
3140
3150
  const errors = [];
3141
- if (!isRecord(response)) {
3151
+ if (!isRecord2(response)) {
3142
3152
  return { ok: false, errors: ["response must be an object"] };
3143
3153
  }
3144
3154
  if (typeof response.success !== "boolean") {
@@ -3157,7 +3167,7 @@ function validateTopoloWidgetResponse(response) {
3157
3167
  return { ok: errors.length === 0, errors };
3158
3168
  }
3159
3169
  function validateWidget(widget, path, errors) {
3160
- if (!isRecord(widget)) {
3170
+ if (!isRecord2(widget)) {
3161
3171
  errors.push(`${path} must be an object`);
3162
3172
  return;
3163
3173
  }
@@ -3184,7 +3194,7 @@ function validateWidget(widget, path, errors) {
3184
3194
  case "chart":
3185
3195
  validateNonEmptyString(widget.chartType, `${path}.chartType`, errors);
3186
3196
  validateNonEmptyString(widget.title, `${path}.title`, errors);
3187
- if (!isRecord(widget.data)) {
3197
+ if (!isRecord2(widget.data)) {
3188
3198
  errors.push(`${path}.data must be an object`);
3189
3199
  } else {
3190
3200
  validateArray(widget.data.labels, `${path}.data.labels`, errors);
@@ -3200,7 +3210,7 @@ function validateSnapshotMetadata(snapshot, path, errors) {
3200
3210
  errors.push(`${path} must be an object`);
3201
3211
  return;
3202
3212
  }
3203
- if (!isRecord(snapshot)) {
3213
+ if (!isRecord2(snapshot)) {
3204
3214
  errors.push(`${path} must be an object`);
3205
3215
  return;
3206
3216
  }
@@ -3220,7 +3230,7 @@ function validateSnapshotMetadata(snapshot, path, errors) {
3220
3230
  }
3221
3231
  snapshot.availableMetrics.forEach((metric, index) => {
3222
3232
  const metricPath = `${path}.availableMetrics[${index}]`;
3223
- if (!isRecord(metric)) {
3233
+ if (!isRecord2(metric)) {
3224
3234
  errors.push(`${metricPath} must be an object`);
3225
3235
  return;
3226
3236
  }
@@ -3241,7 +3251,7 @@ function validateArray(value, path, errors) {
3241
3251
  errors.push(`${path} must be an array`);
3242
3252
  }
3243
3253
  }
3244
- function isRecord(value) {
3254
+ function isRecord2(value) {
3245
3255
  return typeof value === "object" && value !== null && !Array.isArray(value);
3246
3256
  }
3247
3257
  function toIsoTimestamp(input) {