@trops/dash-core 0.1.349 → 0.1.351
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 +374 -341
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +103 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +103 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -26706,6 +26706,334 @@ function parsePackageId(id) {
|
|
|
26706
26706
|
|
|
26707
26707
|
var packageId = { toPackageId: toPackageId$1, parsePackageId };
|
|
26708
26708
|
|
|
26709
|
+
/**
|
|
26710
|
+
* registryAuthController.js
|
|
26711
|
+
*
|
|
26712
|
+
* Manages authentication with the Dash registry service.
|
|
26713
|
+
* Uses OAuth device code flow for desktop app authentication.
|
|
26714
|
+
*
|
|
26715
|
+
* Flow:
|
|
26716
|
+
* 1. App calls initiateDeviceFlow() — gets device code + verification URL
|
|
26717
|
+
* 2. User opens verification URL in browser, signs in, enters code
|
|
26718
|
+
* 3. App polls pollForToken() until authorized
|
|
26719
|
+
* 4. Token stored securely via electron-store (encrypted)
|
|
26720
|
+
*/
|
|
26721
|
+
|
|
26722
|
+
const REGISTRY_BASE_URL$1 =
|
|
26723
|
+
process.env.DASH_REGISTRY_API_URL ||
|
|
26724
|
+
"https://main.d919rwhuzp7rj.amplifyapp.com";
|
|
26725
|
+
|
|
26726
|
+
// Lazy-load electron-store to avoid issues when not installed
|
|
26727
|
+
let store$3 = null;
|
|
26728
|
+
function getStore$1() {
|
|
26729
|
+
if (!store$3) {
|
|
26730
|
+
const Store = require$$1$1;
|
|
26731
|
+
store$3 = new Store({
|
|
26732
|
+
name: "dash-registry-auth",
|
|
26733
|
+
encryptionKey: "dash-registry-v1",
|
|
26734
|
+
});
|
|
26735
|
+
}
|
|
26736
|
+
return store$3;
|
|
26737
|
+
}
|
|
26738
|
+
|
|
26739
|
+
/**
|
|
26740
|
+
* Initiate the OAuth device code flow.
|
|
26741
|
+
* Returns the device code, user code, and verification URL.
|
|
26742
|
+
*
|
|
26743
|
+
* @returns {Promise<Object>} { deviceCode, userCode, verificationUrl, verificationUrlComplete, expiresIn, interval }
|
|
26744
|
+
*/
|
|
26745
|
+
async function initiateDeviceFlow$1() {
|
|
26746
|
+
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/device`, {
|
|
26747
|
+
method: "POST",
|
|
26748
|
+
headers: { "Content-Type": "application/json" },
|
|
26749
|
+
});
|
|
26750
|
+
|
|
26751
|
+
if (!response.ok) {
|
|
26752
|
+
throw new Error(`Device flow initiation failed: ${response.status}`);
|
|
26753
|
+
}
|
|
26754
|
+
|
|
26755
|
+
const data = await response.json();
|
|
26756
|
+
|
|
26757
|
+
return {
|
|
26758
|
+
deviceCode: data.device_code,
|
|
26759
|
+
userCode: data.user_code,
|
|
26760
|
+
verificationUrl: data.verification_uri,
|
|
26761
|
+
verificationUrlComplete: data.verification_uri_complete,
|
|
26762
|
+
expiresIn: data.expires_in,
|
|
26763
|
+
interval: data.interval,
|
|
26764
|
+
};
|
|
26765
|
+
}
|
|
26766
|
+
|
|
26767
|
+
/**
|
|
26768
|
+
* Poll the registry for token after user completes browser auth.
|
|
26769
|
+
*
|
|
26770
|
+
* @param {string} deviceCode - The device code from initiateDeviceFlow()
|
|
26771
|
+
* @returns {Promise<Object>} { status: 'pending' | 'authorized' | 'expired', token?, userId? }
|
|
26772
|
+
*/
|
|
26773
|
+
async function pollForToken$1(deviceCode) {
|
|
26774
|
+
const response = await fetch(
|
|
26775
|
+
`${REGISTRY_BASE_URL$1}/api/auth/device?device_code=${encodeURIComponent(deviceCode)}`,
|
|
26776
|
+
);
|
|
26777
|
+
|
|
26778
|
+
if (response.status === 428) {
|
|
26779
|
+
return { status: "pending" };
|
|
26780
|
+
}
|
|
26781
|
+
|
|
26782
|
+
if (response.status === 400) {
|
|
26783
|
+
const data = await response.json();
|
|
26784
|
+
if (data.error === "expired_token") {
|
|
26785
|
+
return { status: "expired" };
|
|
26786
|
+
}
|
|
26787
|
+
return { status: "pending" };
|
|
26788
|
+
}
|
|
26789
|
+
|
|
26790
|
+
if (response.ok) {
|
|
26791
|
+
const data = await response.json();
|
|
26792
|
+
|
|
26793
|
+
// Store the token securely
|
|
26794
|
+
const s = getStore$1();
|
|
26795
|
+
s.set("accessToken", data.access_token);
|
|
26796
|
+
s.set("userId", data.user_id);
|
|
26797
|
+
s.set("tokenType", data.token_type);
|
|
26798
|
+
s.set("authenticatedAt", new Date().toISOString());
|
|
26799
|
+
|
|
26800
|
+
return {
|
|
26801
|
+
status: "authorized",
|
|
26802
|
+
token: data.access_token,
|
|
26803
|
+
userId: data.user_id,
|
|
26804
|
+
};
|
|
26805
|
+
}
|
|
26806
|
+
|
|
26807
|
+
throw new Error(`Unexpected response: ${response.status}`);
|
|
26808
|
+
}
|
|
26809
|
+
|
|
26810
|
+
/**
|
|
26811
|
+
* Get the stored auth token.
|
|
26812
|
+
*
|
|
26813
|
+
* @returns {Object|null} { token, userId, authenticatedAt } or null if not authenticated
|
|
26814
|
+
*/
|
|
26815
|
+
function getStoredToken$4() {
|
|
26816
|
+
try {
|
|
26817
|
+
const s = getStore$1();
|
|
26818
|
+
const token = s.get("accessToken");
|
|
26819
|
+
if (!token) return null;
|
|
26820
|
+
|
|
26821
|
+
return {
|
|
26822
|
+
token,
|
|
26823
|
+
userId: s.get("userId"),
|
|
26824
|
+
authenticatedAt: s.get("authenticatedAt"),
|
|
26825
|
+
};
|
|
26826
|
+
} catch {
|
|
26827
|
+
return null;
|
|
26828
|
+
}
|
|
26829
|
+
}
|
|
26830
|
+
|
|
26831
|
+
/**
|
|
26832
|
+
* Check if the user is authenticated with the registry.
|
|
26833
|
+
*
|
|
26834
|
+
* @returns {Object} { authenticated: boolean, userId?: string }
|
|
26835
|
+
*/
|
|
26836
|
+
function getAuthStatus$1() {
|
|
26837
|
+
const stored = getStoredToken$4();
|
|
26838
|
+
if (!stored) {
|
|
26839
|
+
return { authenticated: false };
|
|
26840
|
+
}
|
|
26841
|
+
|
|
26842
|
+
return {
|
|
26843
|
+
authenticated: true,
|
|
26844
|
+
userId: stored.userId,
|
|
26845
|
+
authenticatedAt: stored.authenticatedAt,
|
|
26846
|
+
};
|
|
26847
|
+
}
|
|
26848
|
+
|
|
26849
|
+
/**
|
|
26850
|
+
* Get the user's registry profile.
|
|
26851
|
+
*
|
|
26852
|
+
* @returns {Promise<Object|null>} User profile or null
|
|
26853
|
+
*/
|
|
26854
|
+
async function getRegistryProfile$2() {
|
|
26855
|
+
const stored = getStoredToken$4();
|
|
26856
|
+
if (!stored) return null;
|
|
26857
|
+
|
|
26858
|
+
try {
|
|
26859
|
+
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
|
|
26860
|
+
headers: {
|
|
26861
|
+
Authorization: `Bearer ${stored.token}`,
|
|
26862
|
+
},
|
|
26863
|
+
});
|
|
26864
|
+
|
|
26865
|
+
if (response.status === 401) {
|
|
26866
|
+
// Token expired or invalid — clear stored credentials
|
|
26867
|
+
clearToken$2();
|
|
26868
|
+
return null;
|
|
26869
|
+
}
|
|
26870
|
+
if (!response.ok) return null;
|
|
26871
|
+
|
|
26872
|
+
const data = await response.json();
|
|
26873
|
+
return data.user || null;
|
|
26874
|
+
} catch {
|
|
26875
|
+
return null;
|
|
26876
|
+
}
|
|
26877
|
+
}
|
|
26878
|
+
|
|
26879
|
+
/**
|
|
26880
|
+
* Clear stored auth token (logout).
|
|
26881
|
+
*/
|
|
26882
|
+
function clearToken$2() {
|
|
26883
|
+
try {
|
|
26884
|
+
const s = getStore$1();
|
|
26885
|
+
s.clear();
|
|
26886
|
+
console.log("[RegistryAuthController] Token cleared");
|
|
26887
|
+
} catch (err) {
|
|
26888
|
+
console.error("[RegistryAuthController] Error clearing token:", err);
|
|
26889
|
+
}
|
|
26890
|
+
}
|
|
26891
|
+
|
|
26892
|
+
/**
|
|
26893
|
+
* Update the authenticated user's registry profile.
|
|
26894
|
+
*
|
|
26895
|
+
* @param {Object} updates - Fields to update (e.g. { displayName })
|
|
26896
|
+
* @returns {Promise<Object|null>} Updated user or null on 401
|
|
26897
|
+
*/
|
|
26898
|
+
async function updateRegistryProfile$1(updates) {
|
|
26899
|
+
const stored = getStoredToken$4();
|
|
26900
|
+
if (!stored) return null;
|
|
26901
|
+
|
|
26902
|
+
try {
|
|
26903
|
+
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
|
|
26904
|
+
method: "PATCH",
|
|
26905
|
+
headers: {
|
|
26906
|
+
Authorization: `Bearer ${stored.token}`,
|
|
26907
|
+
"Content-Type": "application/json",
|
|
26908
|
+
},
|
|
26909
|
+
body: JSON.stringify(updates),
|
|
26910
|
+
});
|
|
26911
|
+
|
|
26912
|
+
if (response.status === 401) {
|
|
26913
|
+
clearToken$2();
|
|
26914
|
+
return null;
|
|
26915
|
+
}
|
|
26916
|
+
if (!response.ok) return null;
|
|
26917
|
+
|
|
26918
|
+
const data = await response.json();
|
|
26919
|
+
return data.user || null;
|
|
26920
|
+
} catch {
|
|
26921
|
+
return null;
|
|
26922
|
+
}
|
|
26923
|
+
}
|
|
26924
|
+
|
|
26925
|
+
/**
|
|
26926
|
+
* Get the authenticated user's published packages.
|
|
26927
|
+
*
|
|
26928
|
+
* @returns {Promise<Object|null>} { packages: [...] } or null
|
|
26929
|
+
*/
|
|
26930
|
+
async function getRegistryPackages$1() {
|
|
26931
|
+
const stored = getStoredToken$4();
|
|
26932
|
+
if (!stored) return null;
|
|
26933
|
+
|
|
26934
|
+
try {
|
|
26935
|
+
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me/packages`, {
|
|
26936
|
+
headers: {
|
|
26937
|
+
Authorization: `Bearer ${stored.token}`,
|
|
26938
|
+
},
|
|
26939
|
+
});
|
|
26940
|
+
|
|
26941
|
+
if (response.status === 401) {
|
|
26942
|
+
clearToken$2();
|
|
26943
|
+
return null;
|
|
26944
|
+
}
|
|
26945
|
+
if (!response.ok) return null;
|
|
26946
|
+
|
|
26947
|
+
return await response.json();
|
|
26948
|
+
} catch {
|
|
26949
|
+
return null;
|
|
26950
|
+
}
|
|
26951
|
+
}
|
|
26952
|
+
|
|
26953
|
+
/**
|
|
26954
|
+
* Update a published package's metadata.
|
|
26955
|
+
*
|
|
26956
|
+
* @param {string} scope - Package scope (e.g. "@trops")
|
|
26957
|
+
* @param {string} name - Package name
|
|
26958
|
+
* @param {Object} updates - Fields to update (displayName, description, category, tags, visibility)
|
|
26959
|
+
* @returns {Promise<Object|null>} Updated package or null
|
|
26960
|
+
*/
|
|
26961
|
+
async function updateRegistryPackage$1(scope, name, updates) {
|
|
26962
|
+
const stored = getStoredToken$4();
|
|
26963
|
+
if (!stored) return null;
|
|
26964
|
+
|
|
26965
|
+
try {
|
|
26966
|
+
const response = await fetch(
|
|
26967
|
+
`${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
|
|
26968
|
+
{
|
|
26969
|
+
method: "PATCH",
|
|
26970
|
+
headers: {
|
|
26971
|
+
Authorization: `Bearer ${stored.token}`,
|
|
26972
|
+
"Content-Type": "application/json",
|
|
26973
|
+
},
|
|
26974
|
+
body: JSON.stringify(updates),
|
|
26975
|
+
},
|
|
26976
|
+
);
|
|
26977
|
+
|
|
26978
|
+
if (response.status === 401) {
|
|
26979
|
+
clearToken$2();
|
|
26980
|
+
return null;
|
|
26981
|
+
}
|
|
26982
|
+
if (!response.ok) return null;
|
|
26983
|
+
|
|
26984
|
+
return await response.json();
|
|
26985
|
+
} catch {
|
|
26986
|
+
return null;
|
|
26987
|
+
}
|
|
26988
|
+
}
|
|
26989
|
+
|
|
26990
|
+
/**
|
|
26991
|
+
* Delete a published package from the registry.
|
|
26992
|
+
*
|
|
26993
|
+
* @param {string} scope - Package scope (e.g. "@trops")
|
|
26994
|
+
* @param {string} name - Package name
|
|
26995
|
+
* @returns {Promise<Object|null>} Response or null
|
|
26996
|
+
*/
|
|
26997
|
+
async function deleteRegistryPackage(scope, name) {
|
|
26998
|
+
const stored = getStoredToken$4();
|
|
26999
|
+
if (!stored) return null;
|
|
27000
|
+
|
|
27001
|
+
try {
|
|
27002
|
+
const response = await fetch(
|
|
27003
|
+
`${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
|
|
27004
|
+
{
|
|
27005
|
+
method: "DELETE",
|
|
27006
|
+
headers: {
|
|
27007
|
+
Authorization: `Bearer ${stored.token}`,
|
|
27008
|
+
},
|
|
27009
|
+
},
|
|
27010
|
+
);
|
|
27011
|
+
|
|
27012
|
+
if (response.status === 401) {
|
|
27013
|
+
clearToken$2();
|
|
27014
|
+
return null;
|
|
27015
|
+
}
|
|
27016
|
+
if (!response.ok) return null;
|
|
27017
|
+
|
|
27018
|
+
return await response.json();
|
|
27019
|
+
} catch {
|
|
27020
|
+
return null;
|
|
27021
|
+
}
|
|
27022
|
+
}
|
|
27023
|
+
|
|
27024
|
+
var registryAuthController$2 = {
|
|
27025
|
+
initiateDeviceFlow: initiateDeviceFlow$1,
|
|
27026
|
+
pollForToken: pollForToken$1,
|
|
27027
|
+
getStoredToken: getStoredToken$4,
|
|
27028
|
+
getAuthStatus: getAuthStatus$1,
|
|
27029
|
+
getRegistryProfile: getRegistryProfile$2,
|
|
27030
|
+
updateRegistryProfile: updateRegistryProfile$1,
|
|
27031
|
+
getRegistryPackages: getRegistryPackages$1,
|
|
27032
|
+
updateRegistryPackage: updateRegistryPackage$1,
|
|
27033
|
+
deleteRegistryPackage,
|
|
27034
|
+
clearToken: clearToken$2,
|
|
27035
|
+
};
|
|
27036
|
+
|
|
26709
27037
|
/**
|
|
26710
27038
|
* registryController.js
|
|
26711
27039
|
*
|
|
@@ -26721,6 +27049,18 @@ var packageId = { toPackageId: toPackageId$1, parsePackageId };
|
|
|
26721
27049
|
const path$a = require$$1$2;
|
|
26722
27050
|
const fs$6 = require$$0$2;
|
|
26723
27051
|
const { toPackageId } = packageId;
|
|
27052
|
+
const { getStoredToken: getStoredToken$3 } = registryAuthController$2;
|
|
27053
|
+
|
|
27054
|
+
/**
|
|
27055
|
+
* Build request headers for the registry. When the user is signed in, we
|
|
27056
|
+
* include the Bearer token so the server returns private packages that
|
|
27057
|
+
* the user owns or has been granted entitlements for. Anonymous fetches
|
|
27058
|
+
* still work and simply return only public packages.
|
|
27059
|
+
*/
|
|
27060
|
+
function buildAuthHeaders() {
|
|
27061
|
+
const stored = getStoredToken$3();
|
|
27062
|
+
return stored?.token ? { Authorization: `Bearer ${stored.token}` } : {};
|
|
27063
|
+
}
|
|
26724
27064
|
|
|
26725
27065
|
// Default registry API base URL
|
|
26726
27066
|
const DEFAULT_REGISTRY_API_URL = "https://main.d919rwhuzp7rj.amplifyapp.com";
|
|
@@ -26728,8 +27068,15 @@ const DEFAULT_REGISTRY_API_URL = "https://main.d919rwhuzp7rj.amplifyapp.com";
|
|
|
26728
27068
|
// Cache TTL: 5 minutes
|
|
26729
27069
|
const CACHE_TTL_MS = 5 * 60 * 1000;
|
|
26730
27070
|
|
|
26731
|
-
|
|
26732
|
-
|
|
27071
|
+
// Cache is keyed by userId so anonymous + authenticated results don't mix.
|
|
27072
|
+
// When a user signs in, their cache entry is empty and gets populated with
|
|
27073
|
+
// their owned/entitled private packages alongside the public set.
|
|
27074
|
+
const caches = new Map(); // userId | "anon" -> { data, timestamp }
|
|
27075
|
+
|
|
27076
|
+
function getCacheKey() {
|
|
27077
|
+
const stored = getStoredToken$3();
|
|
27078
|
+
return stored?.userId || "anon";
|
|
27079
|
+
}
|
|
26733
27080
|
|
|
26734
27081
|
/**
|
|
26735
27082
|
* Get the local test registry path for dev mode
|
|
@@ -26758,11 +27105,15 @@ function isDev() {
|
|
|
26758
27105
|
*/
|
|
26759
27106
|
async function fetchRegistryIndex(forceRefresh = false) {
|
|
26760
27107
|
const now = Date.now();
|
|
27108
|
+
const cacheKey = getCacheKey();
|
|
27109
|
+
const cached = caches.get(cacheKey);
|
|
26761
27110
|
|
|
26762
27111
|
// Return cached data if still valid
|
|
26763
|
-
if (!forceRefresh &&
|
|
26764
|
-
console.log(
|
|
26765
|
-
|
|
27112
|
+
if (!forceRefresh && cached && now - cached.timestamp < CACHE_TTL_MS) {
|
|
27113
|
+
console.log(
|
|
27114
|
+
`[RegistryController] Returning cached registry index (key=${cacheKey})`,
|
|
27115
|
+
);
|
|
27116
|
+
return cached.data;
|
|
26766
27117
|
}
|
|
26767
27118
|
|
|
26768
27119
|
try {
|
|
@@ -26787,7 +27138,9 @@ async function fetchRegistryIndex(forceRefresh = false) {
|
|
|
26787
27138
|
"[RegistryController] Fetching registry from:",
|
|
26788
27139
|
registryUrl,
|
|
26789
27140
|
);
|
|
26790
|
-
const response = await fetch(registryUrl
|
|
27141
|
+
const response = await fetch(registryUrl, {
|
|
27142
|
+
headers: buildAuthHeaders(),
|
|
27143
|
+
});
|
|
26791
27144
|
if (!response.ok) {
|
|
26792
27145
|
throw new Error(
|
|
26793
27146
|
`Failed to fetch registry: ${response.status} ${response.statusText}`,
|
|
@@ -26802,7 +27155,9 @@ async function fetchRegistryIndex(forceRefresh = false) {
|
|
|
26802
27155
|
`${process.env.DASH_REGISTRY_API_URL || DEFAULT_REGISTRY_API_URL}/api/packages`;
|
|
26803
27156
|
console.log("[RegistryController] Fetching registry from:", registryUrl);
|
|
26804
27157
|
|
|
26805
|
-
const response = await fetch(registryUrl
|
|
27158
|
+
const response = await fetch(registryUrl, {
|
|
27159
|
+
headers: buildAuthHeaders(),
|
|
27160
|
+
});
|
|
26806
27161
|
if (!response.ok) {
|
|
26807
27162
|
throw new Error(
|
|
26808
27163
|
`Failed to fetch registry: ${response.status} ${response.statusText}`,
|
|
@@ -26820,22 +27175,22 @@ async function fetchRegistryIndex(forceRefresh = false) {
|
|
|
26820
27175
|
}
|
|
26821
27176
|
|
|
26822
27177
|
// Cache the result
|
|
26823
|
-
|
|
26824
|
-
cacheTimestamp = now;
|
|
27178
|
+
caches.set(cacheKey, { data: indexData, timestamp: now });
|
|
26825
27179
|
|
|
26826
27180
|
console.log(
|
|
26827
|
-
`[RegistryController] Loaded ${indexData.packages?.length || 0} packages`,
|
|
27181
|
+
`[RegistryController] Loaded ${indexData.packages?.length || 0} packages (key=${cacheKey})`,
|
|
26828
27182
|
);
|
|
26829
27183
|
return indexData;
|
|
26830
27184
|
} catch (error) {
|
|
26831
27185
|
console.error("[RegistryController] Error fetching registry:", error);
|
|
26832
27186
|
|
|
26833
27187
|
// Return stale cache if available
|
|
26834
|
-
|
|
27188
|
+
const stale = caches.get(cacheKey);
|
|
27189
|
+
if (stale) {
|
|
26835
27190
|
console.log(
|
|
26836
27191
|
"[RegistryController] Returning stale cache after fetch error",
|
|
26837
27192
|
);
|
|
26838
|
-
return
|
|
27193
|
+
return stale.data;
|
|
26839
27194
|
}
|
|
26840
27195
|
|
|
26841
27196
|
throw error;
|
|
@@ -49316,334 +49671,6 @@ const mcpDashServerController$4 = {
|
|
|
49316
49671
|
|
|
49317
49672
|
var mcpDashServerController_1 = mcpDashServerController$4;
|
|
49318
49673
|
|
|
49319
|
-
/**
|
|
49320
|
-
* registryAuthController.js
|
|
49321
|
-
*
|
|
49322
|
-
* Manages authentication with the Dash registry service.
|
|
49323
|
-
* Uses OAuth device code flow for desktop app authentication.
|
|
49324
|
-
*
|
|
49325
|
-
* Flow:
|
|
49326
|
-
* 1. App calls initiateDeviceFlow() — gets device code + verification URL
|
|
49327
|
-
* 2. User opens verification URL in browser, signs in, enters code
|
|
49328
|
-
* 3. App polls pollForToken() until authorized
|
|
49329
|
-
* 4. Token stored securely via electron-store (encrypted)
|
|
49330
|
-
*/
|
|
49331
|
-
|
|
49332
|
-
const REGISTRY_BASE_URL$1 =
|
|
49333
|
-
process.env.DASH_REGISTRY_API_URL ||
|
|
49334
|
-
"https://main.d919rwhuzp7rj.amplifyapp.com";
|
|
49335
|
-
|
|
49336
|
-
// Lazy-load electron-store to avoid issues when not installed
|
|
49337
|
-
let store$3 = null;
|
|
49338
|
-
function getStore$1() {
|
|
49339
|
-
if (!store$3) {
|
|
49340
|
-
const Store = require$$1$1;
|
|
49341
|
-
store$3 = new Store({
|
|
49342
|
-
name: "dash-registry-auth",
|
|
49343
|
-
encryptionKey: "dash-registry-v1",
|
|
49344
|
-
});
|
|
49345
|
-
}
|
|
49346
|
-
return store$3;
|
|
49347
|
-
}
|
|
49348
|
-
|
|
49349
|
-
/**
|
|
49350
|
-
* Initiate the OAuth device code flow.
|
|
49351
|
-
* Returns the device code, user code, and verification URL.
|
|
49352
|
-
*
|
|
49353
|
-
* @returns {Promise<Object>} { deviceCode, userCode, verificationUrl, verificationUrlComplete, expiresIn, interval }
|
|
49354
|
-
*/
|
|
49355
|
-
async function initiateDeviceFlow$1() {
|
|
49356
|
-
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/device`, {
|
|
49357
|
-
method: "POST",
|
|
49358
|
-
headers: { "Content-Type": "application/json" },
|
|
49359
|
-
});
|
|
49360
|
-
|
|
49361
|
-
if (!response.ok) {
|
|
49362
|
-
throw new Error(`Device flow initiation failed: ${response.status}`);
|
|
49363
|
-
}
|
|
49364
|
-
|
|
49365
|
-
const data = await response.json();
|
|
49366
|
-
|
|
49367
|
-
return {
|
|
49368
|
-
deviceCode: data.device_code,
|
|
49369
|
-
userCode: data.user_code,
|
|
49370
|
-
verificationUrl: data.verification_uri,
|
|
49371
|
-
verificationUrlComplete: data.verification_uri_complete,
|
|
49372
|
-
expiresIn: data.expires_in,
|
|
49373
|
-
interval: data.interval,
|
|
49374
|
-
};
|
|
49375
|
-
}
|
|
49376
|
-
|
|
49377
|
-
/**
|
|
49378
|
-
* Poll the registry for token after user completes browser auth.
|
|
49379
|
-
*
|
|
49380
|
-
* @param {string} deviceCode - The device code from initiateDeviceFlow()
|
|
49381
|
-
* @returns {Promise<Object>} { status: 'pending' | 'authorized' | 'expired', token?, userId? }
|
|
49382
|
-
*/
|
|
49383
|
-
async function pollForToken$1(deviceCode) {
|
|
49384
|
-
const response = await fetch(
|
|
49385
|
-
`${REGISTRY_BASE_URL$1}/api/auth/device?device_code=${encodeURIComponent(deviceCode)}`,
|
|
49386
|
-
);
|
|
49387
|
-
|
|
49388
|
-
if (response.status === 428) {
|
|
49389
|
-
return { status: "pending" };
|
|
49390
|
-
}
|
|
49391
|
-
|
|
49392
|
-
if (response.status === 400) {
|
|
49393
|
-
const data = await response.json();
|
|
49394
|
-
if (data.error === "expired_token") {
|
|
49395
|
-
return { status: "expired" };
|
|
49396
|
-
}
|
|
49397
|
-
return { status: "pending" };
|
|
49398
|
-
}
|
|
49399
|
-
|
|
49400
|
-
if (response.ok) {
|
|
49401
|
-
const data = await response.json();
|
|
49402
|
-
|
|
49403
|
-
// Store the token securely
|
|
49404
|
-
const s = getStore$1();
|
|
49405
|
-
s.set("accessToken", data.access_token);
|
|
49406
|
-
s.set("userId", data.user_id);
|
|
49407
|
-
s.set("tokenType", data.token_type);
|
|
49408
|
-
s.set("authenticatedAt", new Date().toISOString());
|
|
49409
|
-
|
|
49410
|
-
return {
|
|
49411
|
-
status: "authorized",
|
|
49412
|
-
token: data.access_token,
|
|
49413
|
-
userId: data.user_id,
|
|
49414
|
-
};
|
|
49415
|
-
}
|
|
49416
|
-
|
|
49417
|
-
throw new Error(`Unexpected response: ${response.status}`);
|
|
49418
|
-
}
|
|
49419
|
-
|
|
49420
|
-
/**
|
|
49421
|
-
* Get the stored auth token.
|
|
49422
|
-
*
|
|
49423
|
-
* @returns {Object|null} { token, userId, authenticatedAt } or null if not authenticated
|
|
49424
|
-
*/
|
|
49425
|
-
function getStoredToken$3() {
|
|
49426
|
-
try {
|
|
49427
|
-
const s = getStore$1();
|
|
49428
|
-
const token = s.get("accessToken");
|
|
49429
|
-
if (!token) return null;
|
|
49430
|
-
|
|
49431
|
-
return {
|
|
49432
|
-
token,
|
|
49433
|
-
userId: s.get("userId"),
|
|
49434
|
-
authenticatedAt: s.get("authenticatedAt"),
|
|
49435
|
-
};
|
|
49436
|
-
} catch {
|
|
49437
|
-
return null;
|
|
49438
|
-
}
|
|
49439
|
-
}
|
|
49440
|
-
|
|
49441
|
-
/**
|
|
49442
|
-
* Check if the user is authenticated with the registry.
|
|
49443
|
-
*
|
|
49444
|
-
* @returns {Object} { authenticated: boolean, userId?: string }
|
|
49445
|
-
*/
|
|
49446
|
-
function getAuthStatus$1() {
|
|
49447
|
-
const stored = getStoredToken$3();
|
|
49448
|
-
if (!stored) {
|
|
49449
|
-
return { authenticated: false };
|
|
49450
|
-
}
|
|
49451
|
-
|
|
49452
|
-
return {
|
|
49453
|
-
authenticated: true,
|
|
49454
|
-
userId: stored.userId,
|
|
49455
|
-
authenticatedAt: stored.authenticatedAt,
|
|
49456
|
-
};
|
|
49457
|
-
}
|
|
49458
|
-
|
|
49459
|
-
/**
|
|
49460
|
-
* Get the user's registry profile.
|
|
49461
|
-
*
|
|
49462
|
-
* @returns {Promise<Object|null>} User profile or null
|
|
49463
|
-
*/
|
|
49464
|
-
async function getRegistryProfile$2() {
|
|
49465
|
-
const stored = getStoredToken$3();
|
|
49466
|
-
if (!stored) return null;
|
|
49467
|
-
|
|
49468
|
-
try {
|
|
49469
|
-
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
|
|
49470
|
-
headers: {
|
|
49471
|
-
Authorization: `Bearer ${stored.token}`,
|
|
49472
|
-
},
|
|
49473
|
-
});
|
|
49474
|
-
|
|
49475
|
-
if (response.status === 401) {
|
|
49476
|
-
// Token expired or invalid — clear stored credentials
|
|
49477
|
-
clearToken$2();
|
|
49478
|
-
return null;
|
|
49479
|
-
}
|
|
49480
|
-
if (!response.ok) return null;
|
|
49481
|
-
|
|
49482
|
-
const data = await response.json();
|
|
49483
|
-
return data.user || null;
|
|
49484
|
-
} catch {
|
|
49485
|
-
return null;
|
|
49486
|
-
}
|
|
49487
|
-
}
|
|
49488
|
-
|
|
49489
|
-
/**
|
|
49490
|
-
* Clear stored auth token (logout).
|
|
49491
|
-
*/
|
|
49492
|
-
function clearToken$2() {
|
|
49493
|
-
try {
|
|
49494
|
-
const s = getStore$1();
|
|
49495
|
-
s.clear();
|
|
49496
|
-
console.log("[RegistryAuthController] Token cleared");
|
|
49497
|
-
} catch (err) {
|
|
49498
|
-
console.error("[RegistryAuthController] Error clearing token:", err);
|
|
49499
|
-
}
|
|
49500
|
-
}
|
|
49501
|
-
|
|
49502
|
-
/**
|
|
49503
|
-
* Update the authenticated user's registry profile.
|
|
49504
|
-
*
|
|
49505
|
-
* @param {Object} updates - Fields to update (e.g. { displayName })
|
|
49506
|
-
* @returns {Promise<Object|null>} Updated user or null on 401
|
|
49507
|
-
*/
|
|
49508
|
-
async function updateRegistryProfile$1(updates) {
|
|
49509
|
-
const stored = getStoredToken$3();
|
|
49510
|
-
if (!stored) return null;
|
|
49511
|
-
|
|
49512
|
-
try {
|
|
49513
|
-
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
|
|
49514
|
-
method: "PATCH",
|
|
49515
|
-
headers: {
|
|
49516
|
-
Authorization: `Bearer ${stored.token}`,
|
|
49517
|
-
"Content-Type": "application/json",
|
|
49518
|
-
},
|
|
49519
|
-
body: JSON.stringify(updates),
|
|
49520
|
-
});
|
|
49521
|
-
|
|
49522
|
-
if (response.status === 401) {
|
|
49523
|
-
clearToken$2();
|
|
49524
|
-
return null;
|
|
49525
|
-
}
|
|
49526
|
-
if (!response.ok) return null;
|
|
49527
|
-
|
|
49528
|
-
const data = await response.json();
|
|
49529
|
-
return data.user || null;
|
|
49530
|
-
} catch {
|
|
49531
|
-
return null;
|
|
49532
|
-
}
|
|
49533
|
-
}
|
|
49534
|
-
|
|
49535
|
-
/**
|
|
49536
|
-
* Get the authenticated user's published packages.
|
|
49537
|
-
*
|
|
49538
|
-
* @returns {Promise<Object|null>} { packages: [...] } or null
|
|
49539
|
-
*/
|
|
49540
|
-
async function getRegistryPackages$1() {
|
|
49541
|
-
const stored = getStoredToken$3();
|
|
49542
|
-
if (!stored) return null;
|
|
49543
|
-
|
|
49544
|
-
try {
|
|
49545
|
-
const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me/packages`, {
|
|
49546
|
-
headers: {
|
|
49547
|
-
Authorization: `Bearer ${stored.token}`,
|
|
49548
|
-
},
|
|
49549
|
-
});
|
|
49550
|
-
|
|
49551
|
-
if (response.status === 401) {
|
|
49552
|
-
clearToken$2();
|
|
49553
|
-
return null;
|
|
49554
|
-
}
|
|
49555
|
-
if (!response.ok) return null;
|
|
49556
|
-
|
|
49557
|
-
return await response.json();
|
|
49558
|
-
} catch {
|
|
49559
|
-
return null;
|
|
49560
|
-
}
|
|
49561
|
-
}
|
|
49562
|
-
|
|
49563
|
-
/**
|
|
49564
|
-
* Update a published package's metadata.
|
|
49565
|
-
*
|
|
49566
|
-
* @param {string} scope - Package scope (e.g. "@trops")
|
|
49567
|
-
* @param {string} name - Package name
|
|
49568
|
-
* @param {Object} updates - Fields to update (displayName, description, category, tags, visibility)
|
|
49569
|
-
* @returns {Promise<Object|null>} Updated package or null
|
|
49570
|
-
*/
|
|
49571
|
-
async function updateRegistryPackage$1(scope, name, updates) {
|
|
49572
|
-
const stored = getStoredToken$3();
|
|
49573
|
-
if (!stored) return null;
|
|
49574
|
-
|
|
49575
|
-
try {
|
|
49576
|
-
const response = await fetch(
|
|
49577
|
-
`${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
|
|
49578
|
-
{
|
|
49579
|
-
method: "PATCH",
|
|
49580
|
-
headers: {
|
|
49581
|
-
Authorization: `Bearer ${stored.token}`,
|
|
49582
|
-
"Content-Type": "application/json",
|
|
49583
|
-
},
|
|
49584
|
-
body: JSON.stringify(updates),
|
|
49585
|
-
},
|
|
49586
|
-
);
|
|
49587
|
-
|
|
49588
|
-
if (response.status === 401) {
|
|
49589
|
-
clearToken$2();
|
|
49590
|
-
return null;
|
|
49591
|
-
}
|
|
49592
|
-
if (!response.ok) return null;
|
|
49593
|
-
|
|
49594
|
-
return await response.json();
|
|
49595
|
-
} catch {
|
|
49596
|
-
return null;
|
|
49597
|
-
}
|
|
49598
|
-
}
|
|
49599
|
-
|
|
49600
|
-
/**
|
|
49601
|
-
* Delete a published package from the registry.
|
|
49602
|
-
*
|
|
49603
|
-
* @param {string} scope - Package scope (e.g. "@trops")
|
|
49604
|
-
* @param {string} name - Package name
|
|
49605
|
-
* @returns {Promise<Object|null>} Response or null
|
|
49606
|
-
*/
|
|
49607
|
-
async function deleteRegistryPackage(scope, name) {
|
|
49608
|
-
const stored = getStoredToken$3();
|
|
49609
|
-
if (!stored) return null;
|
|
49610
|
-
|
|
49611
|
-
try {
|
|
49612
|
-
const response = await fetch(
|
|
49613
|
-
`${REGISTRY_BASE_URL$1}/api/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`,
|
|
49614
|
-
{
|
|
49615
|
-
method: "DELETE",
|
|
49616
|
-
headers: {
|
|
49617
|
-
Authorization: `Bearer ${stored.token}`,
|
|
49618
|
-
},
|
|
49619
|
-
},
|
|
49620
|
-
);
|
|
49621
|
-
|
|
49622
|
-
if (response.status === 401) {
|
|
49623
|
-
clearToken$2();
|
|
49624
|
-
return null;
|
|
49625
|
-
}
|
|
49626
|
-
if (!response.ok) return null;
|
|
49627
|
-
|
|
49628
|
-
return await response.json();
|
|
49629
|
-
} catch {
|
|
49630
|
-
return null;
|
|
49631
|
-
}
|
|
49632
|
-
}
|
|
49633
|
-
|
|
49634
|
-
var registryAuthController$2 = {
|
|
49635
|
-
initiateDeviceFlow: initiateDeviceFlow$1,
|
|
49636
|
-
pollForToken: pollForToken$1,
|
|
49637
|
-
getStoredToken: getStoredToken$3,
|
|
49638
|
-
getAuthStatus: getAuthStatus$1,
|
|
49639
|
-
getRegistryProfile: getRegistryProfile$2,
|
|
49640
|
-
updateRegistryProfile: updateRegistryProfile$1,
|
|
49641
|
-
getRegistryPackages: getRegistryPackages$1,
|
|
49642
|
-
updateRegistryPackage: updateRegistryPackage$1,
|
|
49643
|
-
deleteRegistryPackage,
|
|
49644
|
-
clearToken: clearToken$2,
|
|
49645
|
-
};
|
|
49646
|
-
|
|
49647
49674
|
var widgetRegistry$1 = {exports: {}};
|
|
49648
49675
|
|
|
49649
49676
|
var dynamicWidgetLoader$2 = {exports: {}};
|
|
@@ -62711,6 +62738,7 @@ const { toDisplayColor: toDisplayColor$1 } = require$$8;
|
|
|
62711
62738
|
* @param {string} options.category - Registry category (default: "general")
|
|
62712
62739
|
* @param {string} options.repository - Repository URL (optional)
|
|
62713
62740
|
* @param {string} options.appOrigin - Originating app package name (optional)
|
|
62741
|
+
* @param {"public"|"private"} options.visibility - Initial visibility (default: "public")
|
|
62714
62742
|
* @returns {Object} Registry manifest object
|
|
62715
62743
|
*/
|
|
62716
62744
|
function generateRegistryManifest(dashboardConfig, options = {}) {
|
|
@@ -62721,6 +62749,7 @@ function generateRegistryManifest(dashboardConfig, options = {}) {
|
|
|
62721
62749
|
|
|
62722
62750
|
const githubUser = options.githubUser || "";
|
|
62723
62751
|
const version = "1.0.0";
|
|
62752
|
+
const visibility = options.visibility === "private" ? "private" : "public";
|
|
62724
62753
|
|
|
62725
62754
|
const manifest = {
|
|
62726
62755
|
githubUser,
|
|
@@ -62729,6 +62758,7 @@ function generateRegistryManifest(dashboardConfig, options = {}) {
|
|
|
62729
62758
|
author: dashboardConfig.author?.name || "",
|
|
62730
62759
|
description: dashboardConfig.description || "",
|
|
62731
62760
|
version,
|
|
62761
|
+
visibility,
|
|
62732
62762
|
type: "dashboard",
|
|
62733
62763
|
category: options.category || "general",
|
|
62734
62764
|
tags: dashboardConfig.tags || [],
|
|
@@ -63117,13 +63147,14 @@ function sanitizeName(name) {
|
|
|
63117
63147
|
*
|
|
63118
63148
|
* @param {Object} themeData - The raw theme object
|
|
63119
63149
|
* @param {string} themeKey - The theme key/name
|
|
63120
|
-
* @param {Object} options - Publish options { authorName, description, tags, scope }
|
|
63150
|
+
* @param {Object} options - Publish options { authorName, description, tags, scope, visibility }
|
|
63121
63151
|
* @returns {Object} Registry manifest
|
|
63122
63152
|
*/
|
|
63123
63153
|
function generateThemeRegistryManifest(themeData, themeKey, options = {}) {
|
|
63124
63154
|
const humanName = themeData.name || themeKey;
|
|
63125
63155
|
const sanitizedName = sanitizeName(humanName);
|
|
63126
63156
|
const colors = extractColors(themeData);
|
|
63157
|
+
const visibility = options.visibility === "private" ? "private" : "public";
|
|
63127
63158
|
|
|
63128
63159
|
return {
|
|
63129
63160
|
scope: options.scope || "",
|
|
@@ -63132,6 +63163,7 @@ function generateThemeRegistryManifest(themeData, themeKey, options = {}) {
|
|
|
63132
63163
|
author: options.authorName || "",
|
|
63133
63164
|
description: options.description || "",
|
|
63134
63165
|
version: "1.0.0",
|
|
63166
|
+
visibility,
|
|
63135
63167
|
type: "theme",
|
|
63136
63168
|
category: "general",
|
|
63137
63169
|
tags: options.tags || [],
|
|
@@ -64888,6 +64920,7 @@ async function prepareDashboardForPublish$1(
|
|
|
64888
64920
|
category: options.category || "general",
|
|
64889
64921
|
repository: options.repository || "",
|
|
64890
64922
|
appOrigin: appId,
|
|
64923
|
+
visibility: options.visibility || "public",
|
|
64891
64924
|
});
|
|
64892
64925
|
|
|
64893
64926
|
// 9. Show save dialog for the publish package
|