@trops/dash-core 0.1.428 → 0.1.429
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/electron/index.js +229 -30
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +310 -48
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +310 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -472,6 +472,7 @@ const REGISTRY_SEARCH_DASHBOARDS = "registry:search-dashboards";
|
|
|
472
472
|
const REGISTRY_SEARCH_THEMES = "registry:search-themes";
|
|
473
473
|
const REGISTRY_PUBLISH_WIDGET = "registry:publish-widget";
|
|
474
474
|
const REGISTRY_INSPECT_WIDGET_PACKAGE = "registry:inspect-widget-package";
|
|
475
|
+
const REGISTRY_SCAN_WIDGET_DEFAULTS = "registry:scan-widget-defaults";
|
|
475
476
|
const REGISTRY_PREVIEW_FETCH = "registry:preview-fetch";
|
|
476
477
|
|
|
477
478
|
var registryEvents$1 = {
|
|
@@ -483,6 +484,7 @@ var registryEvents$1 = {
|
|
|
483
484
|
REGISTRY_SEARCH_THEMES,
|
|
484
485
|
REGISTRY_PUBLISH_WIDGET,
|
|
485
486
|
REGISTRY_INSPECT_WIDGET_PACKAGE,
|
|
487
|
+
REGISTRY_SCAN_WIDGET_DEFAULTS,
|
|
486
488
|
REGISTRY_PREVIEW_FETCH,
|
|
487
489
|
};
|
|
488
490
|
|
|
@@ -73790,6 +73792,151 @@ async function scanWidgetConfigs(widgetPath) {
|
|
|
73790
73792
|
}
|
|
73791
73793
|
}
|
|
73792
73794
|
|
|
73795
|
+
// ─── Publish-time defaults scan + staged rewrite ─────────────────────────────
|
|
73796
|
+
|
|
73797
|
+
/**
|
|
73798
|
+
* Scan a widget package's `.dash.js` files and return every non-empty
|
|
73799
|
+
* `userConfig[field].defaultValue` as a structured ref. Powers the
|
|
73800
|
+
* publish modal's "Verify defaults" step — surfaces values the
|
|
73801
|
+
* developer set during testing (regional paths, test tokens, etc.)
|
|
73802
|
+
* so the publisher can keep, blank, or edit each one before the ZIP
|
|
73803
|
+
* ships.
|
|
73804
|
+
*
|
|
73805
|
+
* @param {string} packageId e.g. "@ai-built/pipeline"
|
|
73806
|
+
* @returns {Promise<{success: boolean, defaults: Array, error?: string}>}
|
|
73807
|
+
*/
|
|
73808
|
+
async function scanWidgetDefaults$1(packageId) {
|
|
73809
|
+
try {
|
|
73810
|
+
const registry = widgetRegistryModule.getWidgetRegistry();
|
|
73811
|
+
const widget = findWidget(registry, packageId);
|
|
73812
|
+
if (!widget || !widget.path) {
|
|
73813
|
+
return {
|
|
73814
|
+
success: false,
|
|
73815
|
+
error: `Widget package not found locally: ${packageId}`,
|
|
73816
|
+
};
|
|
73817
|
+
}
|
|
73818
|
+
|
|
73819
|
+
const configs = await scanWidgetConfigs(widget.path);
|
|
73820
|
+
const defaults = [];
|
|
73821
|
+
for (const cfg of configs) {
|
|
73822
|
+
const widgetName = cfg.component || cfg.name;
|
|
73823
|
+
if (!widgetName) continue;
|
|
73824
|
+
const userConfig = cfg.userConfig;
|
|
73825
|
+
if (!userConfig || typeof userConfig !== "object") continue;
|
|
73826
|
+
for (const [field, spec] of Object.entries(userConfig)) {
|
|
73827
|
+
if (!spec || typeof spec !== "object") continue;
|
|
73828
|
+
const value = spec.defaultValue;
|
|
73829
|
+
// "non-empty" = not nullish, not empty-string. `false` and `0`
|
|
73830
|
+
// are legitimate defaults (checkbox-off, numeric zero) so we
|
|
73831
|
+
// keep them. Arrays/objects only surface if non-empty.
|
|
73832
|
+
const isEmpty =
|
|
73833
|
+
value === null ||
|
|
73834
|
+
value === undefined ||
|
|
73835
|
+
value === "" ||
|
|
73836
|
+
(Array.isArray(value) && value.length === 0) ||
|
|
73837
|
+
(typeof value === "object" &&
|
|
73838
|
+
!Array.isArray(value) &&
|
|
73839
|
+
Object.keys(value).length === 0);
|
|
73840
|
+
if (isEmpty) continue;
|
|
73841
|
+
defaults.push({
|
|
73842
|
+
widgetName,
|
|
73843
|
+
field,
|
|
73844
|
+
currentDefault: value,
|
|
73845
|
+
displayName: spec.displayName || field,
|
|
73846
|
+
type: spec.type || "text",
|
|
73847
|
+
instructions: spec.instructions || "",
|
|
73848
|
+
});
|
|
73849
|
+
}
|
|
73850
|
+
}
|
|
73851
|
+
return { success: true, defaults };
|
|
73852
|
+
} catch (error) {
|
|
73853
|
+
console.error("[widgetRegistry] scanWidgetDefaults failed:", error);
|
|
73854
|
+
return { success: false, error: error.message };
|
|
73855
|
+
}
|
|
73856
|
+
}
|
|
73857
|
+
|
|
73858
|
+
/**
|
|
73859
|
+
* Return the exported-default object from a `.dash.js` serialized as
|
|
73860
|
+
* pretty-printed JS. We use JSON.stringify (plus a couple of minor
|
|
73861
|
+
* touch-ups) because dash configs are pure data — no functions, no
|
|
73862
|
+
* imports, no regex literals. The source file shape we emit matches
|
|
73863
|
+
* the scaffolded template so dynamicWidgetLoader reads it back
|
|
73864
|
+
* unchanged.
|
|
73865
|
+
*/
|
|
73866
|
+
function serializeDashConfig(config) {
|
|
73867
|
+
const json = JSON.stringify(config, null, 4);
|
|
73868
|
+
return `export default ${json};\n`;
|
|
73869
|
+
}
|
|
73870
|
+
|
|
73871
|
+
/**
|
|
73872
|
+
* Copy a source widget directory into `dstDir`, then rewrite the
|
|
73873
|
+
* `userConfig[field].defaultValue` for every entry in `overrides`.
|
|
73874
|
+
* `overrides` shape: `{ [widgetName]: { [field]: newValue } }`.
|
|
73875
|
+
*
|
|
73876
|
+
* Returns the list of files that were actually rewritten (useful for
|
|
73877
|
+
* the UI / logs). Pure file-system side effect; does NOT touch the
|
|
73878
|
+
* original source directory.
|
|
73879
|
+
*/
|
|
73880
|
+
async function stageOverrides(srcDir, dstDir, overrides) {
|
|
73881
|
+
// Copy the whole package tree into dstDir.
|
|
73882
|
+
fs.cpSync(srcDir, dstDir, {
|
|
73883
|
+
recursive: true,
|
|
73884
|
+
filter: (src) => {
|
|
73885
|
+
const base = path.basename(src);
|
|
73886
|
+
if (ZIP_EXCLUDE_DIRS.has(base)) return false;
|
|
73887
|
+
if (base.startsWith(".")) return false;
|
|
73888
|
+
return true;
|
|
73889
|
+
},
|
|
73890
|
+
});
|
|
73891
|
+
|
|
73892
|
+
if (!overrides || Object.keys(overrides).length === 0) return [];
|
|
73893
|
+
|
|
73894
|
+
const widgetsDir = findWidgetsDir(dstDir) || path.join(dstDir, "widgets");
|
|
73895
|
+
if (!fs.existsSync(widgetsDir)) return [];
|
|
73896
|
+
|
|
73897
|
+
const rewritten = [];
|
|
73898
|
+
const files = fs.readdirSync(widgetsDir);
|
|
73899
|
+
for (const file of files) {
|
|
73900
|
+
if (!file.endsWith(".dash.js")) continue;
|
|
73901
|
+
const filePath = path.join(widgetsDir, file);
|
|
73902
|
+
let cfg;
|
|
73903
|
+
try {
|
|
73904
|
+
// eslint-disable-next-line no-await-in-loop
|
|
73905
|
+
cfg = await dynamicWidgetLoader$1.loadConfigFile(filePath);
|
|
73906
|
+
} catch (err) {
|
|
73907
|
+
console.warn(
|
|
73908
|
+
`[widgetRegistry] Could not load ${file} for override: ${err.message}`,
|
|
73909
|
+
);
|
|
73910
|
+
continue;
|
|
73911
|
+
}
|
|
73912
|
+
if (!cfg || typeof cfg !== "object") continue;
|
|
73913
|
+
const widgetName = cfg.component || cfg.name;
|
|
73914
|
+
if (!widgetName || !overrides[widgetName]) continue;
|
|
73915
|
+
const fieldOverrides = overrides[widgetName];
|
|
73916
|
+
|
|
73917
|
+
if (!cfg.userConfig || typeof cfg.userConfig !== "object") continue;
|
|
73918
|
+
let changed = false;
|
|
73919
|
+
for (const [field, newValue] of Object.entries(fieldOverrides)) {
|
|
73920
|
+
if (!cfg.userConfig[field] || typeof cfg.userConfig[field] !== "object") {
|
|
73921
|
+
continue;
|
|
73922
|
+
}
|
|
73923
|
+
// Undefined = "no change" from the UI side. Explicit null / ""
|
|
73924
|
+
// = user wants to blank it out.
|
|
73925
|
+
if (newValue === undefined) continue;
|
|
73926
|
+
cfg.userConfig[field] = {
|
|
73927
|
+
...cfg.userConfig[field],
|
|
73928
|
+
defaultValue: newValue,
|
|
73929
|
+
};
|
|
73930
|
+
changed = true;
|
|
73931
|
+
}
|
|
73932
|
+
if (!changed) continue;
|
|
73933
|
+
|
|
73934
|
+
fs.writeFileSync(filePath, serializeDashConfig(cfg));
|
|
73935
|
+
rewritten.push(file);
|
|
73936
|
+
}
|
|
73937
|
+
return rewritten;
|
|
73938
|
+
}
|
|
73939
|
+
|
|
73793
73940
|
// ─── ZIP builder ─────────────────────────────────────────────────────────────
|
|
73794
73941
|
|
|
73795
73942
|
const ZIP_EXCLUDE_DIRS = new Set([
|
|
@@ -73983,45 +74130,73 @@ async function prepareWidgetForPublish$1(appId, packageId, options = {}) {
|
|
|
73983
74130
|
appOrigin: appId,
|
|
73984
74131
|
});
|
|
73985
74132
|
|
|
73986
|
-
// 7. Zip the widget directory to a temp file
|
|
74133
|
+
// 7. Zip the widget directory to a temp file. When the caller
|
|
74134
|
+
// supplied `defaultsOverride`, stage a copy of the package
|
|
74135
|
+
// under os.tmpdir() and rewrite the targeted
|
|
74136
|
+
// `userConfig[field].defaultValue` entries there before
|
|
74137
|
+
// zipping — source files on the publisher's machine stay
|
|
74138
|
+
// untouched.
|
|
73987
74139
|
const zipName = `widget-${manifest.scope}-${manifest.name}-v${manifest.version}.zip`;
|
|
73988
74140
|
const zipPath = path.join(app.getPath("temp"), zipName);
|
|
73989
|
-
const
|
|
73990
|
-
|
|
73991
|
-
|
|
74141
|
+
const hasOverrides =
|
|
74142
|
+
options.defaultsOverride &&
|
|
74143
|
+
typeof options.defaultsOverride === "object" &&
|
|
74144
|
+
Object.keys(options.defaultsOverride).length > 0;
|
|
74145
|
+
const stagedDir = hasOverrides
|
|
74146
|
+
? fs.mkdtempSync(path.join(app.getPath("temp"), `dash-publish-stage-`))
|
|
74147
|
+
: null;
|
|
74148
|
+
let registryResult;
|
|
74149
|
+
try {
|
|
74150
|
+
let sourceDir = widget.path;
|
|
74151
|
+
if (stagedDir) {
|
|
74152
|
+
await stageOverrides(widget.path, stagedDir, options.defaultsOverride);
|
|
74153
|
+
sourceDir = stagedDir;
|
|
74154
|
+
}
|
|
74155
|
+
const zip = new AdmZip();
|
|
74156
|
+
addDirToZip(zip, sourceDir);
|
|
74157
|
+
zip.writeZip(zipPath);
|
|
73992
74158
|
|
|
73993
|
-
|
|
73994
|
-
|
|
73995
|
-
|
|
73996
|
-
|
|
73997
|
-
|
|
74159
|
+
// 8. Publish to registry
|
|
74160
|
+
registryResult = await registryApiController$1.publishToRegistry(
|
|
74161
|
+
zipPath,
|
|
74162
|
+
manifest,
|
|
74163
|
+
);
|
|
73998
74164
|
|
|
73999
|
-
|
|
74000
|
-
|
|
74001
|
-
|
|
74165
|
+
// 9. On failure: revert package.json (if we bumped) and surface details
|
|
74166
|
+
if (!registryResult.success) {
|
|
74167
|
+
if (newVersion !== previousVersion) {
|
|
74168
|
+
try {
|
|
74169
|
+
pkgJson.version = previousVersion;
|
|
74170
|
+
fs.writeFileSync(
|
|
74171
|
+
pkgJsonPath,
|
|
74172
|
+
JSON.stringify(pkgJson, null, 2) + "\n",
|
|
74173
|
+
);
|
|
74174
|
+
} catch {
|
|
74175
|
+
/* best effort */
|
|
74176
|
+
}
|
|
74177
|
+
}
|
|
74178
|
+
return {
|
|
74179
|
+
success: false,
|
|
74180
|
+
error: registryResult.error,
|
|
74181
|
+
details: registryResult.details,
|
|
74182
|
+
manifest,
|
|
74183
|
+
};
|
|
74184
|
+
}
|
|
74185
|
+
|
|
74186
|
+
// Clean up the temp zip on success.
|
|
74187
|
+
try {
|
|
74188
|
+
fs.unlinkSync(zipPath);
|
|
74189
|
+
} catch {
|
|
74190
|
+
/* ignore */
|
|
74191
|
+
}
|
|
74192
|
+
} finally {
|
|
74193
|
+
if (stagedDir) {
|
|
74002
74194
|
try {
|
|
74003
|
-
|
|
74004
|
-
fs.writeFileSync(
|
|
74005
|
-
pkgJsonPath,
|
|
74006
|
-
JSON.stringify(pkgJson, null, 2) + "\n",
|
|
74007
|
-
);
|
|
74195
|
+
fs.rmSync(stagedDir, { recursive: true, force: true });
|
|
74008
74196
|
} catch {
|
|
74009
74197
|
/* best effort */
|
|
74010
74198
|
}
|
|
74011
74199
|
}
|
|
74012
|
-
return {
|
|
74013
|
-
success: false,
|
|
74014
|
-
error: registryResult.error,
|
|
74015
|
-
details: registryResult.details,
|
|
74016
|
-
manifest,
|
|
74017
|
-
};
|
|
74018
|
-
}
|
|
74019
|
-
|
|
74020
|
-
// Clean up the temp zip
|
|
74021
|
-
try {
|
|
74022
|
-
fs.unlinkSync(zipPath);
|
|
74023
|
-
} catch {
|
|
74024
|
-
/* ignore */
|
|
74025
74200
|
}
|
|
74026
74201
|
|
|
74027
74202
|
return {
|
|
@@ -74098,6 +74273,7 @@ async function inspectWidgetPackage$1(packageId) {
|
|
|
74098
74273
|
var widgetRegistryController = {
|
|
74099
74274
|
prepareWidgetForPublish: prepareWidgetForPublish$1,
|
|
74100
74275
|
inspectWidgetPackage: inspectWidgetPackage$1,
|
|
74276
|
+
scanWidgetDefaults: scanWidgetDefaults$1,
|
|
74101
74277
|
};
|
|
74102
74278
|
|
|
74103
74279
|
/**
|
|
@@ -74215,6 +74391,7 @@ const {
|
|
|
74215
74391
|
const {
|
|
74216
74392
|
prepareWidgetForPublish,
|
|
74217
74393
|
inspectWidgetPackage,
|
|
74394
|
+
scanWidgetDefaults,
|
|
74218
74395
|
} = widgetRegistryController;
|
|
74219
74396
|
const {
|
|
74220
74397
|
assignRoles,
|
|
@@ -74307,6 +74484,7 @@ var controller = {
|
|
|
74307
74484
|
checkThemeUpdatesForApp,
|
|
74308
74485
|
prepareWidgetForPublish,
|
|
74309
74486
|
inspectWidgetPackage,
|
|
74487
|
+
scanWidgetDefaults,
|
|
74310
74488
|
assignRoles,
|
|
74311
74489
|
matchTailwindFamily,
|
|
74312
74490
|
generateThemeFromPalette,
|
|
@@ -75456,6 +75634,27 @@ const registryApi$2 = {
|
|
|
75456
75634
|
}
|
|
75457
75635
|
},
|
|
75458
75636
|
|
|
75637
|
+
/**
|
|
75638
|
+
* Scan a widget package's `.dash.js` configs and return the list of
|
|
75639
|
+
* non-empty `userConfig[field].defaultValue` entries. Powers the
|
|
75640
|
+
* publish modal's "Verify defaults" step — lets the publisher
|
|
75641
|
+
* review (and optionally blank / edit) values set during
|
|
75642
|
+
* development before the ZIP ships.
|
|
75643
|
+
*
|
|
75644
|
+
* @param {string} packageId - Widget packageId (e.g. "@scope/name")
|
|
75645
|
+
* @returns {Promise<Object>} { success, defaults: [{widgetName, field, currentDefault, displayName, type, instructions}], error? }
|
|
75646
|
+
*/
|
|
75647
|
+
scanWidgetDefaults: async (packageId) => {
|
|
75648
|
+
try {
|
|
75649
|
+
return await ipcRenderer$h.invoke("registry:scan-widget-defaults", {
|
|
75650
|
+
packageId,
|
|
75651
|
+
});
|
|
75652
|
+
} catch (error) {
|
|
75653
|
+
console.error("[RegistryApi] Error scanning widget defaults:", error);
|
|
75654
|
+
throw error;
|
|
75655
|
+
}
|
|
75656
|
+
},
|
|
75657
|
+
|
|
75459
75658
|
/**
|
|
75460
75659
|
* Fetch a registry package's source (component + config + bundle) into a
|
|
75461
75660
|
* temp directory and return the source strings without installing the
|