@trops/dash-core 0.1.415 → 0.1.416

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.
@@ -63867,13 +63867,31 @@ function generateRegistryManifest(dashboardConfig, options = {}) {
63867
63867
  options.callerScope && w.scope && w.scope !== options.callerScope
63868
63868
  ? options.callerScope
63869
63869
  : w.scope || "";
63870
+ // Packaged id — the scoped "@<scope>/<packageName>" string that
63871
+ // the install flow looks up in the registry. Build this from the
63872
+ // REMAPPED scope + bare packageName so installers resolve against
63873
+ // the scope the widget was actually published as, not the local
63874
+ // `@ai-built` convention. Stripping the scope prefix from a
63875
+ // potentially-scoped packageName keeps the result canonical.
63876
+ const bareName = stripScopePrefix(
63877
+ w.packageName || w.package || "",
63878
+ remappedScope || w.scope,
63879
+ );
63880
+ const scopedPackageId = remappedScope
63881
+ ? `@${remappedScope.replace(/^@/, "")}/${bareName}`
63882
+ : bareName;
63870
63883
  return {
63871
63884
  id: w.id,
63872
63885
  scope: remappedScope,
63873
- packageName: w.packageName || w.package || "",
63886
+ packageName: bareName,
63874
63887
  widgetName: w.widgetName || (w.id ? w.id.split(".").pop() : w.package),
63875
63888
  name: w.id ? w.id.split(".").pop() : w.package,
63876
- package: w.package,
63889
+ // `package` is consumed by the install flow as the registry
63890
+ // package id (see installDashboardFromRegistry in
63891
+ // dashboardConfigController.js). Must carry the remapped
63892
+ // scope, otherwise installers look up an @ai-built/... id that
63893
+ // only exists on the publisher's machine.
63894
+ package: scopedPackageId,
63877
63895
  version: w.version || "*",
63878
63896
  required: w.required !== false,
63879
63897
  author: w.author || "",
@@ -64151,6 +64169,67 @@ function extractEventWiringFromWorkspace$1(workspace) {
64151
64169
  return wiring;
64152
64170
  }
64153
64171
 
64172
+ /**
64173
+ * Strip publisher-specific personalization (userPrefs + selectedProviders)
64174
+ * from every widget instance in a layout-ish structure. Used by the
64175
+ * dashboard publish flow so the installer starts with the widget's
64176
+ * own defaultValue on every field instead of inheriting the
64177
+ * publisher's absolute paths, region tags, credentials, etc.
64178
+ *
64179
+ * Walks the standard layout shapes that forEachWidget handles:
64180
+ * - top-level `layout` arrays
64181
+ * - `workspace.pages[*].layout`
64182
+ * - `workspace.sidebarLayout`
64183
+ * - `LayoutGridContainer` children stored on `item.items` / `item.layout`
64184
+ *
64185
+ * Returns a deep copy — never mutates the input workspace.
64186
+ *
64187
+ * Title-ish defaults (widget.name) are intentionally preserved — they
64188
+ * are part of the dashboard template, not personal data. Anything else
64189
+ * under userPrefs is dropped; the installer's widget re-reads the
64190
+ * `defaultValue` declared in the component's `.dash.js`.
64191
+ */
64192
+ function stripPersonalizationFromWorkspace$1(workspace) {
64193
+ if (!workspace) return workspace;
64194
+ const cleanItem = (item) => {
64195
+ if (!item || typeof item !== "object") return item;
64196
+ // Preserve the layout position + children, but blank out the
64197
+ // user-set config values that are tied to the publisher's machine.
64198
+ const cleaned = { ...item };
64199
+ if ("userPrefs" in cleaned) delete cleaned.userPrefs;
64200
+ if ("selectedProviders" in cleaned) delete cleaned.selectedProviders;
64201
+ if (Array.isArray(cleaned.items)) {
64202
+ cleaned.items = cleaned.items.map(cleanItem);
64203
+ }
64204
+ if (Array.isArray(cleaned.layout)) {
64205
+ cleaned.layout = cleaned.layout.map(cleanItem);
64206
+ }
64207
+ return cleaned;
64208
+ };
64209
+ const cleaned = { ...workspace };
64210
+ if (Array.isArray(cleaned.layout))
64211
+ cleaned.layout = cleaned.layout.map(cleanItem);
64212
+ if (Array.isArray(cleaned.sidebarLayout))
64213
+ cleaned.sidebarLayout = cleaned.sidebarLayout.map(cleanItem);
64214
+ if (Array.isArray(cleaned.pages)) {
64215
+ cleaned.pages = cleaned.pages.map((page) =>
64216
+ page
64217
+ ? {
64218
+ ...page,
64219
+ ...(Array.isArray(page.layout)
64220
+ ? { layout: page.layout.map(cleanItem) }
64221
+ : {}),
64222
+ }
64223
+ : page,
64224
+ );
64225
+ }
64226
+ // Workspace-level selectedProviders map lives at the top level for
64227
+ // some older workspaces; drop it too so the installer doesn't get
64228
+ // bindings to provider names that don't exist on their machine.
64229
+ if ("selectedProviders" in cleaned) delete cleaned.selectedProviders;
64230
+ return cleaned;
64231
+ }
64232
+
64154
64233
  var dashboardConfigUtils$1 = {
64155
64234
  collectComponentNames: collectComponentNames$1,
64156
64235
  collectComponentNamesFromWorkspace: collectComponentNamesFromWorkspace$1,
@@ -64165,6 +64244,7 @@ var dashboardConfigUtils$1 = {
64165
64244
  checkDashboardUpdates,
64166
64245
  buildProviderSetupManifest,
64167
64246
  checkApiCompatibility,
64247
+ stripPersonalizationFromWorkspace: stripPersonalizationFromWorkspace$1,
64168
64248
  };
64169
64249
 
64170
64250
  /**
@@ -64910,6 +64990,7 @@ const {
64910
64990
  buildWidgetDependencies,
64911
64991
  buildProviderRequirements,
64912
64992
  applyEventWiringToLayout,
64993
+ stripPersonalizationFromWorkspace,
64913
64994
  } = dashboardConfigUtils$1;
64914
64995
  const { searchRegistry, getPackage } = registryController$3;
64915
64996
  const { getStoredToken, clearToken } = registryAuthController$2;
@@ -64957,7 +65038,11 @@ async function exportDashboardConfig$1(
64957
65038
  };
64958
65039
  }
64959
65040
 
64960
- const layout = workspace.layout || [];
65041
+ // Strip publisher-specific personalization (userPrefs,
65042
+ // selectedProviders) so the exported file carries a clean
65043
+ // template, not one pre-filled with the publisher's paths.
65044
+ const sharedWorkspace = stripPersonalizationFromWorkspace(workspace);
65045
+ const layout = sharedWorkspace.layout || [];
64961
65046
 
64962
65047
  // 2. Collect components, extract wiring, resolve deps — walk main
64963
65048
  // layout, every page, and the sidebar so multi-page / sidebar
@@ -64985,13 +65070,17 @@ async function exportDashboardConfig$1(
64985
65070
  label: workspace.label || workspace.name,
64986
65071
  version: workspace.version || 1,
64987
65072
  layout,
64988
- ...(Array.isArray(workspace.pages) && workspace.pages.length > 0
64989
- ? { pages: workspace.pages, activePageId: workspace.activePageId }
65073
+ ...(Array.isArray(sharedWorkspace.pages) &&
65074
+ sharedWorkspace.pages.length > 0
65075
+ ? {
65076
+ pages: sharedWorkspace.pages,
65077
+ activePageId: workspace.activePageId,
65078
+ }
64990
65079
  : {}),
64991
- ...(Array.isArray(workspace.sidebarLayout) &&
64992
- workspace.sidebarLayout.length > 0
65080
+ ...(Array.isArray(sharedWorkspace.sidebarLayout) &&
65081
+ sharedWorkspace.sidebarLayout.length > 0
64993
65082
  ? {
64994
- sidebarLayout: workspace.sidebarLayout,
65083
+ sidebarLayout: sharedWorkspace.sidebarLayout,
64995
65084
  sidebarEnabled: workspace.sidebarEnabled !== false,
64996
65085
  }
64997
65086
  : {}),
@@ -66243,7 +66332,16 @@ async function prepareDashboardForPublish$1(
66243
66332
  };
66244
66333
  }
66245
66334
 
66246
- const layout = workspace.layout || [];
66335
+ // Strip publisher-specific personalization (userPrefs,
66336
+ // selectedProviders) from every widget instance before we snapshot
66337
+ // the workspace into the dashboardConfig. Without this, every
66338
+ // installer inherits the publisher's absolute filesystem paths,
66339
+ // region tags, and provider bindings as their "defaults" — a
66340
+ // widget's own `defaultValue` on each field never gets a chance.
66341
+ // Layout position, ordering, nested containers, and any title text
66342
+ // are preserved (they're part of the template, not personal).
66343
+ const sharedWorkspace = stripPersonalizationFromWorkspace(workspace);
66344
+ const layout = sharedWorkspace.layout || [];
66247
66345
 
66248
66346
  // 3. Build the dashboard config — walk main + pages + sidebar
66249
66347
  const componentNames = collectComponentNamesFromWorkspace(workspace);
@@ -66283,13 +66381,17 @@ async function prepareDashboardForPublish$1(
66283
66381
  label: workspace.label || workspace.name,
66284
66382
  version: workspace.version || 1,
66285
66383
  layout,
66286
- ...(Array.isArray(workspace.pages) && workspace.pages.length > 0
66287
- ? { pages: workspace.pages, activePageId: workspace.activePageId }
66384
+ ...(Array.isArray(sharedWorkspace.pages) &&
66385
+ sharedWorkspace.pages.length > 0
66386
+ ? {
66387
+ pages: sharedWorkspace.pages,
66388
+ activePageId: workspace.activePageId,
66389
+ }
66288
66390
  : {}),
66289
- ...(Array.isArray(workspace.sidebarLayout) &&
66290
- workspace.sidebarLayout.length > 0
66391
+ ...(Array.isArray(sharedWorkspace.sidebarLayout) &&
66392
+ sharedWorkspace.sidebarLayout.length > 0
66291
66393
  ? {
66292
- sidebarLayout: workspace.sidebarLayout,
66394
+ sidebarLayout: sharedWorkspace.sidebarLayout,
66293
66395
  sidebarEnabled: workspace.sidebarEnabled !== false,
66294
66396
  }
66295
66397
  : {}),