@rool-dev/extension 0.3.12-dev.7733a35 → 0.3.12-dev.902bec7
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/cli/publish.js
CHANGED
|
@@ -55,7 +55,7 @@ export async function publish() {
|
|
|
55
55
|
// Publish
|
|
56
56
|
console.log(` Publishing ${manifest.id} to ${env}...`);
|
|
57
57
|
const blob = new Blob([new Uint8Array(zipBuffer)], { type: 'application/zip' });
|
|
58
|
-
const result = await client.
|
|
58
|
+
const result = await client.uploadExtension(manifest.id, {
|
|
59
59
|
bundle: blob,
|
|
60
60
|
});
|
|
61
61
|
console.log(`\n Published: ${result.manifest.name}`);
|
|
@@ -227,7 +227,7 @@ export class DevHostController {
|
|
|
227
227
|
return;
|
|
228
228
|
try {
|
|
229
229
|
// Step 1: install extension (server applies manifest: name, systemInstruction, collections)
|
|
230
|
-
const channelId = await this.client.installExtension(this.currentSpaceId, extensionId);
|
|
230
|
+
const channelId = await this.client.installExtension(this.currentSpaceId, extensionId, extensionId);
|
|
231
231
|
// Step 2: open channel for live subscription
|
|
232
232
|
const ch = await this.client.openChannel(this.currentSpaceId, channelId);
|
|
233
233
|
this.channels[extensionId] = ch;
|
|
@@ -283,7 +283,7 @@ export class DevHostController {
|
|
|
283
283
|
// Step 2: publish via SDK
|
|
284
284
|
this.publishState = 'uploading';
|
|
285
285
|
this._onChange();
|
|
286
|
-
const result = await this.client.
|
|
286
|
+
const result = await this.client.uploadExtension(this.manifest.id, {
|
|
287
287
|
bundle: zipBlob,
|
|
288
288
|
});
|
|
289
289
|
// Step 3: update published extensions list
|
package/dist/dev/Sidebar.svelte
CHANGED
|
@@ -274,7 +274,7 @@
|
|
|
274
274
|
<!-- Footer -->
|
|
275
275
|
<div class="px-4 py-3 mt-auto flex items-center justify-between">
|
|
276
276
|
<a
|
|
277
|
-
href="https://docs.rool.dev/extension"
|
|
277
|
+
href="https://docs.rool.dev/extension/"
|
|
278
278
|
target="_blank"
|
|
279
279
|
rel="noopener noreferrer"
|
|
280
280
|
class="text-[11px] text-slate-400 hover:text-indigo-500 transition-colors"
|
package/dist/dev/host-shell.js
CHANGED
|
@@ -4556,11 +4556,12 @@ var BrowserAuthProvider = class {
|
|
|
4556
4556
|
* Initiate login by redirecting to auth page.
|
|
4557
4557
|
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
4558
4558
|
*/
|
|
4559
|
-
login(appName) {
|
|
4559
|
+
login(appName, options) {
|
|
4560
4560
|
const loginUrl = new URL(`${this.authBaseUrl}/`);
|
|
4561
4561
|
const redirectTarget = window.location.origin + window.location.pathname + window.location.search;
|
|
4562
4562
|
loginUrl.searchParams.set("redirect_uri", redirectTarget);
|
|
4563
4563
|
loginUrl.searchParams.set("app_name", appName);
|
|
4564
|
+
if (options?.signup) loginUrl.searchParams.set("signup", "true");
|
|
4564
4565
|
const state = this.generateState();
|
|
4565
4566
|
this.storeState(state);
|
|
4566
4567
|
loginUrl.searchParams.set("state", state);
|
|
@@ -4833,8 +4834,8 @@ var AuthManager = class {
|
|
|
4833
4834
|
* Initiate login.
|
|
4834
4835
|
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
4835
4836
|
*/
|
|
4836
|
-
login(appName) {
|
|
4837
|
-
return this.provider.login(appName);
|
|
4837
|
+
login(appName, options) {
|
|
4838
|
+
return this.provider.login(appName, options);
|
|
4838
4839
|
}
|
|
4839
4840
|
/**
|
|
4840
4841
|
* Logout - clear all tokens and state.
|
|
@@ -5443,6 +5444,7 @@ var GraphQLClient = class {
|
|
|
5443
5444
|
createdByName
|
|
5444
5445
|
interactionCount
|
|
5445
5446
|
extensionUrl
|
|
5447
|
+
extensionId
|
|
5446
5448
|
}
|
|
5447
5449
|
}
|
|
5448
5450
|
}
|
|
@@ -5835,6 +5837,20 @@ var GraphQLClient = class {
|
|
|
5835
5837
|
channelId
|
|
5836
5838
|
})).installExtension;
|
|
5837
5839
|
}
|
|
5840
|
+
async publishExtensionToPublic(extensionId) {
|
|
5841
|
+
await this.request(`
|
|
5842
|
+
mutation PublishExtension($extensionId: String!) {
|
|
5843
|
+
publishExtension(extensionId: $extensionId)
|
|
5844
|
+
}
|
|
5845
|
+
`, { extensionId });
|
|
5846
|
+
}
|
|
5847
|
+
async unpublishExtensionFromPublic(extensionId) {
|
|
5848
|
+
await this.request(`
|
|
5849
|
+
mutation UnpublishExtension($extensionId: String!) {
|
|
5850
|
+
unpublishExtension(extensionId: $extensionId)
|
|
5851
|
+
}
|
|
5852
|
+
`, { extensionId });
|
|
5853
|
+
}
|
|
5838
5854
|
async setUserStorage(key, value) {
|
|
5839
5855
|
await this.request(`
|
|
5840
5856
|
mutation SetUserStorage($key: String!, $value: JSON) {
|
|
@@ -7259,81 +7275,65 @@ var ExtensionsClient = class {
|
|
|
7259
7275
|
constructor(config) {
|
|
7260
7276
|
this.config = config;
|
|
7261
7277
|
}
|
|
7262
|
-
|
|
7263
|
-
* List all published extensions for the current user.
|
|
7264
|
-
*/
|
|
7265
|
-
async list() {
|
|
7278
|
+
async getHeaders() {
|
|
7266
7279
|
const tokens = await this.config.authManager.getTokens();
|
|
7267
7280
|
if (!tokens) throw new Error("Not authenticated");
|
|
7268
|
-
|
|
7281
|
+
return {
|
|
7269
7282
|
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7270
7283
|
"X-Rool-Token": tokens.roolToken
|
|
7271
7284
|
};
|
|
7285
|
+
}
|
|
7286
|
+
/**
|
|
7287
|
+
* List all user extensions.
|
|
7288
|
+
*/
|
|
7289
|
+
async list() {
|
|
7272
7290
|
const response = await fetch(this.config.extensionsUrl, {
|
|
7273
7291
|
method: "GET",
|
|
7274
|
-
headers
|
|
7292
|
+
headers: await this.getHeaders()
|
|
7275
7293
|
});
|
|
7276
7294
|
if (!response.ok) throw new Error(`Failed to list extensions: ${response.status} ${response.statusText}`);
|
|
7277
7295
|
return response.json();
|
|
7278
7296
|
}
|
|
7279
7297
|
/**
|
|
7280
|
-
* Get info for a specific
|
|
7298
|
+
* Get info for a specific user extension.
|
|
7281
7299
|
*/
|
|
7282
7300
|
async get(extensionId) {
|
|
7283
|
-
const tokens = await this.config.authManager.getTokens();
|
|
7284
|
-
if (!tokens) throw new Error("Not authenticated");
|
|
7285
|
-
const headers = {
|
|
7286
|
-
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7287
|
-
"X-Rool-Token": tokens.roolToken
|
|
7288
|
-
};
|
|
7289
7301
|
const response = await fetch(`${this.config.extensionsUrl}/${encodeURIComponent(extensionId)}`, {
|
|
7290
7302
|
method: "GET",
|
|
7291
|
-
headers
|
|
7303
|
+
headers: await this.getHeaders()
|
|
7292
7304
|
});
|
|
7293
7305
|
if (response.status === 404) return null;
|
|
7294
7306
|
if (!response.ok) throw new Error(`Failed to get extension: ${response.status} ${response.statusText}`);
|
|
7295
7307
|
return response.json();
|
|
7296
7308
|
}
|
|
7297
7309
|
/**
|
|
7298
|
-
*
|
|
7310
|
+
* Upload or update a user extension bundle.
|
|
7299
7311
|
* @param extensionId - URL-safe identifier for the extension
|
|
7300
7312
|
* @param options - Bundle zip file (must include index.html and manifest.json)
|
|
7301
7313
|
*/
|
|
7302
|
-
async
|
|
7303
|
-
const tokens = await this.config.authManager.getTokens();
|
|
7304
|
-
if (!tokens) throw new Error("Not authenticated");
|
|
7305
|
-
const headers = {
|
|
7306
|
-
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7307
|
-
"X-Rool-Token": tokens.roolToken
|
|
7308
|
-
};
|
|
7314
|
+
async upload(extensionId, options) {
|
|
7309
7315
|
const formData = new FormData();
|
|
7310
7316
|
formData.append("bundle", options.bundle);
|
|
7311
7317
|
const response = await fetch(`${this.config.extensionsUrl}/${encodeURIComponent(extensionId)}`, {
|
|
7312
7318
|
method: "POST",
|
|
7313
|
-
headers,
|
|
7319
|
+
headers: await this.getHeaders(),
|
|
7314
7320
|
body: formData
|
|
7315
7321
|
});
|
|
7316
7322
|
if (!response.ok) {
|
|
7317
7323
|
const errorMessage = (await response.json().catch(() => ({}))).error || `${response.status} ${response.statusText}`;
|
|
7318
|
-
throw new Error(`Failed to
|
|
7324
|
+
throw new Error(`Failed to upload extension: ${errorMessage}`);
|
|
7319
7325
|
}
|
|
7320
7326
|
return response.json();
|
|
7321
7327
|
}
|
|
7322
7328
|
/**
|
|
7323
|
-
*
|
|
7329
|
+
* Delete a user extension permanently.
|
|
7324
7330
|
*/
|
|
7325
|
-
async
|
|
7326
|
-
const tokens = await this.config.authManager.getTokens();
|
|
7327
|
-
if (!tokens) throw new Error("Not authenticated");
|
|
7328
|
-
const headers = {
|
|
7329
|
-
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7330
|
-
"X-Rool-Token": tokens.roolToken
|
|
7331
|
-
};
|
|
7331
|
+
async delete(extensionId) {
|
|
7332
7332
|
const response = await fetch(`${this.config.extensionsUrl}/${encodeURIComponent(extensionId)}`, {
|
|
7333
7333
|
method: "DELETE",
|
|
7334
|
-
headers
|
|
7334
|
+
headers: await this.getHeaders()
|
|
7335
7335
|
});
|
|
7336
|
-
if (!response.ok && response.status !== 204) throw new Error(`Failed to
|
|
7336
|
+
if (!response.ok && response.status !== 204) throw new Error(`Failed to delete extension: ${response.status} ${response.statusText}`);
|
|
7337
7337
|
}
|
|
7338
7338
|
};
|
|
7339
7339
|
//#endregion
|
|
@@ -7498,6 +7498,12 @@ var RoolChannel = class extends EventEmitter {
|
|
|
7498
7498
|
return this._channel?.extensionUrl ?? null;
|
|
7499
7499
|
}
|
|
7500
7500
|
/**
|
|
7501
|
+
* Get the extension ID if this channel has an installed extension, or null.
|
|
7502
|
+
*/
|
|
7503
|
+
get extensionId() {
|
|
7504
|
+
return this._channel?.extensionId ?? null;
|
|
7505
|
+
}
|
|
7506
|
+
/**
|
|
7501
7507
|
* Get the active branch of the current conversation as a flat array (root → leaf).
|
|
7502
7508
|
* Walks from the active leaf up through parentId pointers.
|
|
7503
7509
|
*/
|
|
@@ -8573,7 +8579,7 @@ var RoolClient = class extends EventEmitter {
|
|
|
8573
8579
|
graphql: config.graphqlUrl ?? `${this.baseUrl}/graphql`,
|
|
8574
8580
|
media: config.mediaUrl ?? `${this.baseUrl}/media`,
|
|
8575
8581
|
auth: config.authUrl ?? `${this.baseUrl}/auth`,
|
|
8576
|
-
extensions: `${this.baseUrl}/extensions`
|
|
8582
|
+
extensions: `${this.baseUrl}/user-extensions`
|
|
8577
8583
|
};
|
|
8578
8584
|
this.authManager = new AuthManager({
|
|
8579
8585
|
authUrl: this.urls.auth,
|
|
@@ -8621,8 +8627,8 @@ var RoolClient = class extends EventEmitter {
|
|
|
8621
8627
|
* Initiate login by redirecting to auth page.
|
|
8622
8628
|
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
8623
8629
|
*/
|
|
8624
|
-
async login(appName) {
|
|
8625
|
-
return this.authManager.login(appName);
|
|
8630
|
+
async login(appName, options) {
|
|
8631
|
+
return this.authManager.login(appName, options);
|
|
8626
8632
|
}
|
|
8627
8633
|
/**
|
|
8628
8634
|
* Logout - clear all tokens and state.
|
|
@@ -8818,53 +8824,48 @@ var RoolClient = class extends EventEmitter {
|
|
|
8818
8824
|
return user;
|
|
8819
8825
|
}
|
|
8820
8826
|
/**
|
|
8821
|
-
*
|
|
8822
|
-
*
|
|
8823
|
-
*
|
|
8824
|
-
* @param extensionId - URL-safe identifier (alphanumeric, hyphens, underscores; case-insensitive, lowercased by server)
|
|
8827
|
+
* Upload or update a user extension bundle.
|
|
8828
|
+
* @param extensionId - URL-safe identifier (alphanumeric, hyphens, underscores)
|
|
8825
8829
|
* @param options - Bundle zip file (must include index.html and manifest.json)
|
|
8826
8830
|
*/
|
|
8827
|
-
async
|
|
8828
|
-
return this.extensionsClient.
|
|
8831
|
+
async uploadExtension(extensionId, options) {
|
|
8832
|
+
return this.extensionsClient.upload(extensionId, options);
|
|
8829
8833
|
}
|
|
8830
|
-
/**
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
async unpublishExtension(extensionId) {
|
|
8834
|
-
return this.extensionsClient.unpublish(extensionId);
|
|
8834
|
+
/** Delete a user extension permanently (removes files and DB row). */
|
|
8835
|
+
async deleteExtension(extensionId) {
|
|
8836
|
+
return this.extensionsClient.delete(extensionId);
|
|
8835
8837
|
}
|
|
8836
|
-
/**
|
|
8837
|
-
* List all published extensions for the current user.
|
|
8838
|
-
*/
|
|
8838
|
+
/** List the current user's extensions. */
|
|
8839
8839
|
async listExtensions() {
|
|
8840
8840
|
return this.extensionsClient.list();
|
|
8841
8841
|
}
|
|
8842
|
-
/**
|
|
8843
|
-
* Get info for a specific published extension.
|
|
8844
|
-
* Returns null if the extension doesn't exist.
|
|
8845
|
-
*/
|
|
8842
|
+
/** Get info for a specific user extension. Returns null if not found. */
|
|
8846
8843
|
async getExtensionInfo(extensionId) {
|
|
8847
8844
|
return this.extensionsClient.get(extensionId);
|
|
8848
8845
|
}
|
|
8849
8846
|
/**
|
|
8850
|
-
* Search
|
|
8851
|
-
* Without a query, returns all
|
|
8847
|
+
* Search published extensions. With a query, performs semantic search.
|
|
8848
|
+
* Without a query, returns all published extensions sorted by most recently updated.
|
|
8852
8849
|
*/
|
|
8853
8850
|
async findExtensions(options) {
|
|
8854
8851
|
return this.graphqlClient.findExtensions(options);
|
|
8855
8852
|
}
|
|
8856
8853
|
/**
|
|
8857
8854
|
* Install an extension into a space.
|
|
8858
|
-
*
|
|
8859
|
-
* and
|
|
8860
|
-
*
|
|
8861
|
-
* @param spaceId - The space to install the extension into
|
|
8862
|
-
* @param extensionId - The published extension ID
|
|
8863
|
-
* @param channelId - Channel ID for the extension (defaults to extensionId)
|
|
8855
|
+
* If extensionId is a user extension you own, wires it directly.
|
|
8856
|
+
* If it's a published extension, copies source and builds a new user extension.
|
|
8864
8857
|
* @returns The channel ID
|
|
8865
8858
|
*/
|
|
8866
8859
|
async installExtension(spaceId, extensionId, channelId) {
|
|
8867
|
-
return this.graphqlClient.installExtension(spaceId, extensionId, channelId
|
|
8860
|
+
return this.graphqlClient.installExtension(spaceId, extensionId, channelId);
|
|
8861
|
+
}
|
|
8862
|
+
/** Publish a user extension (make it publicly discoverable). */
|
|
8863
|
+
async publishToPublic(extensionId) {
|
|
8864
|
+
return this.graphqlClient.publishExtensionToPublic(extensionId);
|
|
8865
|
+
}
|
|
8866
|
+
/** Unpublish an extension (remove from public listing). */
|
|
8867
|
+
async unpublishFromPublic(extensionId) {
|
|
8868
|
+
return this.graphqlClient.unpublishExtensionFromPublic(extensionId);
|
|
8868
8869
|
}
|
|
8869
8870
|
/**
|
|
8870
8871
|
* Get a value from user storage (sync read from local cache).
|
|
@@ -9021,7 +9022,8 @@ var RoolClient = class extends EventEmitter {
|
|
|
9021
9022
|
createdBy: event.channelCreatedBy ?? "",
|
|
9022
9023
|
createdByName: event.channelCreatedByName ?? null,
|
|
9023
9024
|
interactionCount: 0,
|
|
9024
|
-
extensionUrl: event.channelExtensionUrl ?? null
|
|
9025
|
+
extensionUrl: event.channelExtensionUrl ?? null,
|
|
9026
|
+
extensionId: event.channelExtensionId ?? null
|
|
9025
9027
|
});
|
|
9026
9028
|
break;
|
|
9027
9029
|
case "channel_renamed":
|
|
@@ -9462,7 +9464,7 @@ var DevHostController = class {
|
|
|
9462
9464
|
if (!this.currentSpaceId) return;
|
|
9463
9465
|
if (this.installedExtensionIds.includes(extensionId)) return;
|
|
9464
9466
|
try {
|
|
9465
|
-
const channelId = await this.client.installExtension(this.currentSpaceId, extensionId);
|
|
9467
|
+
const channelId = await this.client.installExtension(this.currentSpaceId, extensionId, extensionId);
|
|
9466
9468
|
const ch = await this.client.openChannel(this.currentSpaceId, channelId);
|
|
9467
9469
|
this.channels[extensionId] = ch;
|
|
9468
9470
|
this.installedExtensionIds = [...this.installedExtensionIds, extensionId];
|
|
@@ -9507,7 +9509,7 @@ var DevHostController = class {
|
|
|
9507
9509
|
const zipBlob = await buildRes.blob();
|
|
9508
9510
|
this.publishState = "uploading";
|
|
9509
9511
|
this._onChange();
|
|
9510
|
-
const result = await this.client.
|
|
9512
|
+
const result = await this.client.uploadExtension(this.manifest.id, { bundle: zipBlob });
|
|
9511
9513
|
const existingIdx = this.publishedExtensions.findIndex((a) => a.extensionId === result.extensionId);
|
|
9512
9514
|
if (existingIdx >= 0) this.publishedExtensions = [
|
|
9513
9515
|
...this.publishedExtensions.slice(0, existingIdx),
|
|
@@ -9656,7 +9658,7 @@ var root_29 = /* @__PURE__ */ from_html(`<div class="text-[11px] text-red-500 mt
|
|
|
9656
9658
|
var root_22 = /* @__PURE__ */ from_html(`<div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Publish</div> <button><!></button> <!></div>`);
|
|
9657
9659
|
var root_30 = /* @__PURE__ */ from_svg(`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>`);
|
|
9658
9660
|
var root_31 = /* @__PURE__ */ from_svg(`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>`);
|
|
9659
|
-
var root_2$1 = /* @__PURE__ */ from_html(`<div class="w-[280px] shrink-0 bg-white border-r border-slate-200 flex flex-col overflow-y-auto"><div class="px-4 pt-4 pb-3 border-b border-slate-100"><div class="flex items-start justify-between mb-1"><!> <button class="p-1 -mr-1 text-slate-400 hover:text-slate-600 transition-colors shrink-0" title="Collapse sidebar"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"></path></svg></button></div> <!> <!> <!></div> <!> <!> <!> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Environment</div> <div class="flex rounded-md border border-slate-200 overflow-hidden"><button>Local</button> <button>Dev</button> <button>Prod</button></div> <div class="text-[10px] text-slate-400 mt-1 font-mono"> </div></div> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Space</div> <div class="relative" data-dropdown=""><button type="button"> <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"></path></svg></button> <!></div> <div class="text-[11px] text-slate-400 leading-normal mt-1.5"><span></span> </div></div> <!> <div class="px-4 py-3 mt-auto flex items-center justify-between"><a href="https://docs.rool.dev/extension" target="_blank" rel="noopener noreferrer" class="text-[11px] text-slate-400 hover:text-indigo-500 transition-colors">Documentation</a> <button class="p-1 text-slate-400 hover:text-indigo-500 transition-colors"><!></button> <button class="text-[11px] text-slate-400 hover:text-red-500 transition-colors">Sign out</button></div></div>`);
|
|
9661
|
+
var root_2$1 = /* @__PURE__ */ from_html(`<div class="w-[280px] shrink-0 bg-white border-r border-slate-200 flex flex-col overflow-y-auto"><div class="px-4 pt-4 pb-3 border-b border-slate-100"><div class="flex items-start justify-between mb-1"><!> <button class="p-1 -mr-1 text-slate-400 hover:text-slate-600 transition-colors shrink-0" title="Collapse sidebar"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"></path></svg></button></div> <!> <!> <!></div> <!> <!> <!> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Environment</div> <div class="flex rounded-md border border-slate-200 overflow-hidden"><button>Local</button> <button>Dev</button> <button>Prod</button></div> <div class="text-[10px] text-slate-400 mt-1 font-mono"> </div></div> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Space</div> <div class="relative" data-dropdown=""><button type="button"> <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"></path></svg></button> <!></div> <div class="text-[11px] text-slate-400 leading-normal mt-1.5"><span></span> </div></div> <!> <div class="px-4 py-3 mt-auto flex items-center justify-between"><a href="https://docs.rool.dev/extension/" target="_blank" rel="noopener noreferrer" class="text-[11px] text-slate-400 hover:text-indigo-500 transition-colors">Documentation</a> <button class="p-1 text-slate-400 hover:text-indigo-500 transition-colors"><!></button> <button class="text-[11px] text-slate-400 hover:text-red-500 transition-colors">Sign out</button></div></div>`);
|
|
9660
9662
|
function Sidebar($$anchor, $$props) {
|
|
9661
9663
|
push($$props, true);
|
|
9662
9664
|
let dropdownOpen = prop($$props, "dropdownOpen", 15);
|