@rool-dev/extension 0.3.14 → 0.4.0-dev.35f9ee7
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 +1 -1
- package/dist/dev/DevHostController.js +2 -2
- package/dist/dev/host-shell.js +100 -76
- package/dist/dev/host-shell.js.map +1 -1
- package/package.json +2 -2
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/host-shell.js
CHANGED
|
@@ -4556,16 +4556,25 @@ 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
|
|
4560
|
-
|
|
4559
|
+
login(appName) {
|
|
4560
|
+
this.redirectToAuth("login", appName);
|
|
4561
|
+
}
|
|
4562
|
+
/**
|
|
4563
|
+
* Initiate signup by redirecting to auth page.
|
|
4564
|
+
* @param appName - The name of the application requesting signup (displayed on auth page)
|
|
4565
|
+
*/
|
|
4566
|
+
signup(appName) {
|
|
4567
|
+
this.redirectToAuth("signup", appName);
|
|
4568
|
+
}
|
|
4569
|
+
redirectToAuth(flow, appName) {
|
|
4570
|
+
const url = new URL(`${this.authBaseUrl}/${flow}`);
|
|
4561
4571
|
const redirectTarget = window.location.origin + window.location.pathname + window.location.search;
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
if (options?.signup) loginUrl.searchParams.set("signup", "true");
|
|
4572
|
+
url.searchParams.set("redirect_uri", redirectTarget);
|
|
4573
|
+
url.searchParams.set("app_name", appName);
|
|
4565
4574
|
const state = this.generateState();
|
|
4566
4575
|
this.storeState(state);
|
|
4567
|
-
|
|
4568
|
-
window.location.href =
|
|
4576
|
+
url.searchParams.set("state", state);
|
|
4577
|
+
window.location.href = url.toString();
|
|
4569
4578
|
}
|
|
4570
4579
|
/**
|
|
4571
4580
|
* Logout - clear all tokens and state.
|
|
@@ -4834,8 +4843,15 @@ var AuthManager = class {
|
|
|
4834
4843
|
* Initiate login.
|
|
4835
4844
|
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
4836
4845
|
*/
|
|
4837
|
-
login(appName
|
|
4838
|
-
return this.provider.login(appName
|
|
4846
|
+
login(appName) {
|
|
4847
|
+
return this.provider.login(appName);
|
|
4848
|
+
}
|
|
4849
|
+
/**
|
|
4850
|
+
* Initiate signup.
|
|
4851
|
+
* @param appName - The name of the application requesting signup (displayed on auth page)
|
|
4852
|
+
*/
|
|
4853
|
+
signup(appName) {
|
|
4854
|
+
return this.provider.signup(appName);
|
|
4839
4855
|
}
|
|
4840
4856
|
/**
|
|
4841
4857
|
* Logout - clear all tokens and state.
|
|
@@ -5444,6 +5460,7 @@ var GraphQLClient = class {
|
|
|
5444
5460
|
createdByName
|
|
5445
5461
|
interactionCount
|
|
5446
5462
|
extensionUrl
|
|
5463
|
+
extensionId
|
|
5447
5464
|
}
|
|
5448
5465
|
}
|
|
5449
5466
|
}
|
|
@@ -5836,6 +5853,20 @@ var GraphQLClient = class {
|
|
|
5836
5853
|
channelId
|
|
5837
5854
|
})).installExtension;
|
|
5838
5855
|
}
|
|
5856
|
+
async publishExtensionToPublic(extensionId) {
|
|
5857
|
+
await this.request(`
|
|
5858
|
+
mutation PublishExtension($extensionId: String!) {
|
|
5859
|
+
publishExtension(extensionId: $extensionId)
|
|
5860
|
+
}
|
|
5861
|
+
`, { extensionId });
|
|
5862
|
+
}
|
|
5863
|
+
async unpublishExtensionFromPublic(extensionId) {
|
|
5864
|
+
await this.request(`
|
|
5865
|
+
mutation UnpublishExtension($extensionId: String!) {
|
|
5866
|
+
unpublishExtension(extensionId: $extensionId)
|
|
5867
|
+
}
|
|
5868
|
+
`, { extensionId });
|
|
5869
|
+
}
|
|
5839
5870
|
async setUserStorage(key, value) {
|
|
5840
5871
|
await this.request(`
|
|
5841
5872
|
mutation SetUserStorage($key: String!, $value: JSON) {
|
|
@@ -7260,81 +7291,65 @@ var ExtensionsClient = class {
|
|
|
7260
7291
|
constructor(config) {
|
|
7261
7292
|
this.config = config;
|
|
7262
7293
|
}
|
|
7263
|
-
|
|
7264
|
-
* List all published extensions for the current user.
|
|
7265
|
-
*/
|
|
7266
|
-
async list() {
|
|
7294
|
+
async getHeaders() {
|
|
7267
7295
|
const tokens = await this.config.authManager.getTokens();
|
|
7268
7296
|
if (!tokens) throw new Error("Not authenticated");
|
|
7269
|
-
|
|
7297
|
+
return {
|
|
7270
7298
|
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7271
7299
|
"X-Rool-Token": tokens.roolToken
|
|
7272
7300
|
};
|
|
7301
|
+
}
|
|
7302
|
+
/**
|
|
7303
|
+
* List all user extensions.
|
|
7304
|
+
*/
|
|
7305
|
+
async list() {
|
|
7273
7306
|
const response = await fetch(this.config.extensionsUrl, {
|
|
7274
7307
|
method: "GET",
|
|
7275
|
-
headers
|
|
7308
|
+
headers: await this.getHeaders()
|
|
7276
7309
|
});
|
|
7277
7310
|
if (!response.ok) throw new Error(`Failed to list extensions: ${response.status} ${response.statusText}`);
|
|
7278
7311
|
return response.json();
|
|
7279
7312
|
}
|
|
7280
7313
|
/**
|
|
7281
|
-
* Get info for a specific
|
|
7314
|
+
* Get info for a specific user extension.
|
|
7282
7315
|
*/
|
|
7283
7316
|
async get(extensionId) {
|
|
7284
|
-
const tokens = await this.config.authManager.getTokens();
|
|
7285
|
-
if (!tokens) throw new Error("Not authenticated");
|
|
7286
|
-
const headers = {
|
|
7287
|
-
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7288
|
-
"X-Rool-Token": tokens.roolToken
|
|
7289
|
-
};
|
|
7290
7317
|
const response = await fetch(`${this.config.extensionsUrl}/${encodeURIComponent(extensionId)}`, {
|
|
7291
7318
|
method: "GET",
|
|
7292
|
-
headers
|
|
7319
|
+
headers: await this.getHeaders()
|
|
7293
7320
|
});
|
|
7294
7321
|
if (response.status === 404) return null;
|
|
7295
7322
|
if (!response.ok) throw new Error(`Failed to get extension: ${response.status} ${response.statusText}`);
|
|
7296
7323
|
return response.json();
|
|
7297
7324
|
}
|
|
7298
7325
|
/**
|
|
7299
|
-
*
|
|
7326
|
+
* Upload or update a user extension bundle.
|
|
7300
7327
|
* @param extensionId - URL-safe identifier for the extension
|
|
7301
7328
|
* @param options - Bundle zip file (must include index.html and manifest.json)
|
|
7302
7329
|
*/
|
|
7303
|
-
async
|
|
7304
|
-
const tokens = await this.config.authManager.getTokens();
|
|
7305
|
-
if (!tokens) throw new Error("Not authenticated");
|
|
7306
|
-
const headers = {
|
|
7307
|
-
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7308
|
-
"X-Rool-Token": tokens.roolToken
|
|
7309
|
-
};
|
|
7330
|
+
async upload(extensionId, options) {
|
|
7310
7331
|
const formData = new FormData();
|
|
7311
7332
|
formData.append("bundle", options.bundle);
|
|
7312
7333
|
const response = await fetch(`${this.config.extensionsUrl}/${encodeURIComponent(extensionId)}`, {
|
|
7313
7334
|
method: "POST",
|
|
7314
|
-
headers,
|
|
7335
|
+
headers: await this.getHeaders(),
|
|
7315
7336
|
body: formData
|
|
7316
7337
|
});
|
|
7317
7338
|
if (!response.ok) {
|
|
7318
7339
|
const errorMessage = (await response.json().catch(() => ({}))).error || `${response.status} ${response.statusText}`;
|
|
7319
|
-
throw new Error(`Failed to
|
|
7340
|
+
throw new Error(`Failed to upload extension: ${errorMessage}`);
|
|
7320
7341
|
}
|
|
7321
7342
|
return response.json();
|
|
7322
7343
|
}
|
|
7323
7344
|
/**
|
|
7324
|
-
*
|
|
7345
|
+
* Delete a user extension permanently.
|
|
7325
7346
|
*/
|
|
7326
|
-
async
|
|
7327
|
-
const tokens = await this.config.authManager.getTokens();
|
|
7328
|
-
if (!tokens) throw new Error("Not authenticated");
|
|
7329
|
-
const headers = {
|
|
7330
|
-
Authorization: `Bearer ${tokens.accessToken}`,
|
|
7331
|
-
"X-Rool-Token": tokens.roolToken
|
|
7332
|
-
};
|
|
7347
|
+
async delete(extensionId) {
|
|
7333
7348
|
const response = await fetch(`${this.config.extensionsUrl}/${encodeURIComponent(extensionId)}`, {
|
|
7334
7349
|
method: "DELETE",
|
|
7335
|
-
headers
|
|
7350
|
+
headers: await this.getHeaders()
|
|
7336
7351
|
});
|
|
7337
|
-
if (!response.ok && response.status !== 204) throw new Error(`Failed to
|
|
7352
|
+
if (!response.ok && response.status !== 204) throw new Error(`Failed to delete extension: ${response.status} ${response.statusText}`);
|
|
7338
7353
|
}
|
|
7339
7354
|
};
|
|
7340
7355
|
//#endregion
|
|
@@ -7499,6 +7514,12 @@ var RoolChannel = class extends EventEmitter {
|
|
|
7499
7514
|
return this._channel?.extensionUrl ?? null;
|
|
7500
7515
|
}
|
|
7501
7516
|
/**
|
|
7517
|
+
* Get the extension ID if this channel has an installed extension, or null.
|
|
7518
|
+
*/
|
|
7519
|
+
get extensionId() {
|
|
7520
|
+
return this._channel?.extensionId ?? null;
|
|
7521
|
+
}
|
|
7522
|
+
/**
|
|
7502
7523
|
* Get the active branch of the current conversation as a flat array (root → leaf).
|
|
7503
7524
|
* Walks from the active leaf up through parentId pointers.
|
|
7504
7525
|
*/
|
|
@@ -8574,7 +8595,7 @@ var RoolClient = class extends EventEmitter {
|
|
|
8574
8595
|
graphql: config.graphqlUrl ?? `${this.baseUrl}/graphql`,
|
|
8575
8596
|
media: config.mediaUrl ?? `${this.baseUrl}/media`,
|
|
8576
8597
|
auth: config.authUrl ?? `${this.baseUrl}/auth`,
|
|
8577
|
-
extensions: `${this.baseUrl}/extensions`
|
|
8598
|
+
extensions: `${this.baseUrl}/user-extensions`
|
|
8578
8599
|
};
|
|
8579
8600
|
this.authManager = new AuthManager({
|
|
8580
8601
|
authUrl: this.urls.auth,
|
|
@@ -8622,8 +8643,15 @@ var RoolClient = class extends EventEmitter {
|
|
|
8622
8643
|
* Initiate login by redirecting to auth page.
|
|
8623
8644
|
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
8624
8645
|
*/
|
|
8625
|
-
async login(appName
|
|
8626
|
-
return this.authManager.login(appName
|
|
8646
|
+
async login(appName) {
|
|
8647
|
+
return this.authManager.login(appName);
|
|
8648
|
+
}
|
|
8649
|
+
/**
|
|
8650
|
+
* Initiate signup by redirecting to auth page.
|
|
8651
|
+
* @param appName - The name of the application requesting signup (displayed on auth page)
|
|
8652
|
+
*/
|
|
8653
|
+
async signup(appName) {
|
|
8654
|
+
return this.authManager.signup(appName);
|
|
8627
8655
|
}
|
|
8628
8656
|
/**
|
|
8629
8657
|
* Logout - clear all tokens and state.
|
|
@@ -8819,53 +8847,48 @@ var RoolClient = class extends EventEmitter {
|
|
|
8819
8847
|
return user;
|
|
8820
8848
|
}
|
|
8821
8849
|
/**
|
|
8822
|
-
*
|
|
8823
|
-
*
|
|
8824
|
-
*
|
|
8825
|
-
* @param extensionId - URL-safe identifier (alphanumeric, hyphens, underscores; case-insensitive, lowercased by server)
|
|
8850
|
+
* Upload or update a user extension bundle.
|
|
8851
|
+
* @param extensionId - URL-safe identifier (alphanumeric, hyphens, underscores)
|
|
8826
8852
|
* @param options - Bundle zip file (must include index.html and manifest.json)
|
|
8827
8853
|
*/
|
|
8828
|
-
async
|
|
8829
|
-
return this.extensionsClient.
|
|
8854
|
+
async uploadExtension(extensionId, options) {
|
|
8855
|
+
return this.extensionsClient.upload(extensionId, options);
|
|
8830
8856
|
}
|
|
8831
|
-
/**
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
async unpublishExtension(extensionId) {
|
|
8835
|
-
return this.extensionsClient.unpublish(extensionId);
|
|
8857
|
+
/** Delete a user extension permanently (removes files and DB row). */
|
|
8858
|
+
async deleteExtension(extensionId) {
|
|
8859
|
+
return this.extensionsClient.delete(extensionId);
|
|
8836
8860
|
}
|
|
8837
|
-
/**
|
|
8838
|
-
* List all published extensions for the current user.
|
|
8839
|
-
*/
|
|
8861
|
+
/** List the current user's extensions. */
|
|
8840
8862
|
async listExtensions() {
|
|
8841
8863
|
return this.extensionsClient.list();
|
|
8842
8864
|
}
|
|
8843
|
-
/**
|
|
8844
|
-
* Get info for a specific published extension.
|
|
8845
|
-
* Returns null if the extension doesn't exist.
|
|
8846
|
-
*/
|
|
8865
|
+
/** Get info for a specific user extension. Returns null if not found. */
|
|
8847
8866
|
async getExtensionInfo(extensionId) {
|
|
8848
8867
|
return this.extensionsClient.get(extensionId);
|
|
8849
8868
|
}
|
|
8850
8869
|
/**
|
|
8851
|
-
* Search
|
|
8852
|
-
* Without a query, returns all
|
|
8870
|
+
* Search published extensions. With a query, performs semantic search.
|
|
8871
|
+
* Without a query, returns all published extensions sorted by most recently updated.
|
|
8853
8872
|
*/
|
|
8854
8873
|
async findExtensions(options) {
|
|
8855
8874
|
return this.graphqlClient.findExtensions(options);
|
|
8856
8875
|
}
|
|
8857
8876
|
/**
|
|
8858
8877
|
* Install an extension into a space.
|
|
8859
|
-
*
|
|
8860
|
-
* and
|
|
8861
|
-
*
|
|
8862
|
-
* @param spaceId - The space to install the extension into
|
|
8863
|
-
* @param extensionId - The published extension ID
|
|
8864
|
-
* @param channelId - Channel ID for the extension (defaults to extensionId)
|
|
8878
|
+
* If extensionId is a user extension you own, wires it directly.
|
|
8879
|
+
* If it's a published extension, copies source and builds a new user extension.
|
|
8865
8880
|
* @returns The channel ID
|
|
8866
8881
|
*/
|
|
8867
8882
|
async installExtension(spaceId, extensionId, channelId) {
|
|
8868
|
-
return this.graphqlClient.installExtension(spaceId, extensionId, channelId
|
|
8883
|
+
return this.graphqlClient.installExtension(spaceId, extensionId, channelId);
|
|
8884
|
+
}
|
|
8885
|
+
/** Publish a user extension (make it publicly discoverable). */
|
|
8886
|
+
async publishToPublic(extensionId) {
|
|
8887
|
+
return this.graphqlClient.publishExtensionToPublic(extensionId);
|
|
8888
|
+
}
|
|
8889
|
+
/** Unpublish an extension (remove from public listing). */
|
|
8890
|
+
async unpublishFromPublic(extensionId) {
|
|
8891
|
+
return this.graphqlClient.unpublishExtensionFromPublic(extensionId);
|
|
8869
8892
|
}
|
|
8870
8893
|
/**
|
|
8871
8894
|
* Get a value from user storage (sync read from local cache).
|
|
@@ -9022,7 +9045,8 @@ var RoolClient = class extends EventEmitter {
|
|
|
9022
9045
|
createdBy: event.channelCreatedBy ?? "",
|
|
9023
9046
|
createdByName: event.channelCreatedByName ?? null,
|
|
9024
9047
|
interactionCount: 0,
|
|
9025
|
-
extensionUrl: event.channelExtensionUrl ?? null
|
|
9048
|
+
extensionUrl: event.channelExtensionUrl ?? null,
|
|
9049
|
+
extensionId: event.channelExtensionId ?? null
|
|
9026
9050
|
});
|
|
9027
9051
|
break;
|
|
9028
9052
|
case "channel_renamed":
|
|
@@ -9463,7 +9487,7 @@ var DevHostController = class {
|
|
|
9463
9487
|
if (!this.currentSpaceId) return;
|
|
9464
9488
|
if (this.installedExtensionIds.includes(extensionId)) return;
|
|
9465
9489
|
try {
|
|
9466
|
-
const channelId = await this.client.installExtension(this.currentSpaceId, extensionId);
|
|
9490
|
+
const channelId = await this.client.installExtension(this.currentSpaceId, extensionId, extensionId);
|
|
9467
9491
|
const ch = await this.client.openChannel(this.currentSpaceId, channelId);
|
|
9468
9492
|
this.channels[extensionId] = ch;
|
|
9469
9493
|
this.installedExtensionIds = [...this.installedExtensionIds, extensionId];
|
|
@@ -9508,7 +9532,7 @@ var DevHostController = class {
|
|
|
9508
9532
|
const zipBlob = await buildRes.blob();
|
|
9509
9533
|
this.publishState = "uploading";
|
|
9510
9534
|
this._onChange();
|
|
9511
|
-
const result = await this.client.
|
|
9535
|
+
const result = await this.client.uploadExtension(this.manifest.id, { bundle: zipBlob });
|
|
9512
9536
|
const existingIdx = this.publishedExtensions.findIndex((a) => a.extensionId === result.extensionId);
|
|
9513
9537
|
if (existingIdx >= 0) this.publishedExtensions = [
|
|
9514
9538
|
...this.publishedExtensions.slice(0, existingIdx),
|