From c4b703370472ffe09eeebf6c6c506c480c2fe146 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Mon, 10 Aug 2026 11:37:01 +0100 Subject: [PATCH 1/9] Move round feature enablement part of FlowFuse/engineering#230 --- forge/ee/lib/index.js | 125 +++++++++++++++++++++++++-------------- forge/ee/routes/index.js | 67 +++++++++++++++------ 2 files changed, 128 insertions(+), 64 deletions(-) diff --git a/forge/ee/lib/index.js b/forge/ee/lib/index.js index dff8995d87..81ca1f0b92 100644 --- a/forge/ee/lib/index.js +++ b/forge/ee/lib/index.js @@ -1,66 +1,99 @@ const fp = require('fastify-plugin') +// common features across all higher tier (enterpise, hub, edge, fleet) +async function commonFeatures(app, opts) { + app.decorate('sso', await require('./sso').init(app)) + await require('./teamBroker').init(app) + // Set the MFA Feature Flag + app.config.features.register('mfa', true, true) + // Set the Project History timeline Feature Flag + app.config.features.register('projectHistory', true, true) + // Set the Bill of Materials Feature Flag + app.config.features.register('bom', true, true) + if (app.config.npmRegistry?.enabled) { + // Set npm Feature Flag + app.config.features.register('npm', true, true) + } + if (app.config.tables?.enabled) { + app.decorate('tables', await require('./tables').init(app)) + } + app.config.features.register('certifiedNodes', true, true) + app.config.features.register('ffNodes', true, true) + // Application level RBAC + app.config.features.register('rbacApplication', true, true) + require('./autoUpdateStacks').init(app) + + // Expert + await app.register(require('./expert')) + + // Set the AI Features Flag (global gate for all AI features) + const isAiEnabled = !!(app.config?.ai?.enabled ?? true) + app.config.features.register('ai', isAiEnabled, true) + + // Set the Generate Snapshot Description Feature Flag + const isAssistantConfigured = isAiEnabled && app.config.assistant?.enabled === true && !!app.config.assistant?.service?.url + app.config.features.register('generatedSnapshotDescription', isAssistantConfigured, true) + + // Set the assistant inline completions Feature Flag + app.config.features.register('assistantInlineCompletions', isAssistantConfigured, true) + + // Set the expert platform automation Feature Flag (MCP platform tools server) + app.config.features.register('expertPlatformAutomation', isAiEnabled && (app.config?.expert?.enabled ?? false), true) + + // Set the expert assistant Feature Flag + app.config.features.register('expertAssistant', isAiEnabled && (app.config?.expert?.enabled ?? false), true) + + // Set the Expert Insights flag + const isInsightsEnabled = isAiEnabled && + !!app.config?.expert?.enabled && + (Object.prototype.hasOwnProperty.call(app.config?.expert ?? {}, 'insights') ? !!app.config?.expert?.insights?.enabled : true) + + app.config.features.register('expertInsights', isInsightsEnabled ?? false, true) +} + module.exports = fp(async function (app, opts) { if (app.config.billing) { app.decorate('billing', await require('./billing').init(app)) } + // common features for all license levels (inc Pro) require('./projectComms').init(app) require('./deviceEditor').init(app) require('./alerts').init(app) if (app.license.get('tier') === 'enterprise') { + await commonFeatures(app, opts) + // HA require('./ha').init(app) + // Protected Instances require('./protectedInstance').init(app) + // Git Opps + app.decorate('gitops', await require('./gitops').init(app)) require('./customHostnames').init(app) - app.decorate('sso', await require('./sso').init(app)) - await require('./teamBroker').init(app) + + // Set the Device Groups Feature Flag + app.config.features.register('deviceGroups', true, true) + + } else if (app.license.get('tier') === 'hub') { + await commonFeatures(app, opts) + // HA + require('./ha').init(app) + // Protected Instances + require('./protectedInstance').init(app) + // Git Opps app.decorate('gitops', await require('./gitops').init(app)) - // Set the MFA Feature Flag - app.config.features.register('mfa', true, true) + + } else if (app.license.get('tier') === 'edge') { + await commonFeatures(app, opts) // Set the Device Groups Feature Flag app.config.features.register('deviceGroups', true, true) - // Set the Project History timeline Feature Flag - app.config.features.register('projectHistory', true, true) - // Set the Bill of Materials Feature Flag - app.config.features.register('bom', true, true) - if (app.config.npmRegistry?.enabled) { - // Set npm Feature Flag - app.config.features.register('npm', true, true) - } - if (app.config.tables?.enabled) { - app.decorate('tables', await require('./tables').init(app)) - } - app.config.features.register('certifiedNodes', true, true) - app.config.features.register('ffNodes', true, true) - app.config.features.register('rbacApplication', true, true) - require('./autoUpdateStacks').init(app) - - // Expert - await app.register(require('./expert')) - - // Set the AI Features Flag (global gate for all AI features) - const isAiEnabled = !!(app.config?.ai?.enabled ?? true) - app.config.features.register('ai', isAiEnabled, true) - - // Set the Generate Snapshot Description Feature Flag - const isAssistantConfigured = isAiEnabled && app.config.assistant?.enabled === true && !!app.config.assistant?.service?.url - app.config.features.register('generatedSnapshotDescription', isAssistantConfigured, true) - - // Set the assistant inline completions Feature Flag - app.config.features.register('assistantInlineCompletions', isAssistantConfigured, true) - - // Set the expert platform automation Feature Flag (MCP platform tools server) - app.config.features.register('expertPlatformAutomation', isAiEnabled && (app.config?.expert?.enabled ?? false), true) - - // Set the expert assistant Feature Flag - app.config.features.register('expertAssistant', isAiEnabled && (app.config?.expert?.enabled ?? false), true) - - // Set the Expert Insights flag - const isInsightsEnabled = isAiEnabled && - !!app.config?.expert?.enabled && - (Object.prototype.hasOwnProperty.call(app.config?.expert ?? {}, 'insights') ? !!app.config?.expert?.insights?.enabled : true) - - app.config.features.register('expertInsights', isInsightsEnabled ?? false, true) + + } else if (app.license.get('tier') === 'fleet') { + await commonFeatures(app, opts) + // Set the Device Groups Feature Flag + app.config.features.register('deviceGroups', true, true) + + } else { + // old "Pro" license } // Set the Team Library Feature Flag diff --git a/forge/ee/routes/index.js b/forge/ee/routes/index.js index 14ef4c5b03..1c3a967657 100644 --- a/forge/ee/routes/index.js +++ b/forge/ee/routes/index.js @@ -4,11 +4,35 @@ * @namespace api * @memberof forge.ee */ + +// common features across all higher tier (enterpise, hub, edge, fleet) +async function commonFeatures(app) { + await app.register(require('./expert'), { prefix: '/api/v1/expert', logLevel: app.config.logging.http }) + await app.register(require('./mcp'), { logLevel: app.config.logging.http }) + await app.register(require('./teamBroker'), { prefix: '/api/v1/teams/:teamId/broker', logLevel: app.config.logging.http }) + await app.register(require('./teamBroker/3rdPartyBroker'), { prefix: '/api/v1/teams/:teamId/brokers', logLevel: app.config.logging.http }) + if (app.config.npmRegistry?.enabled) { + await app.register(require('./catalogues'), { prefix: '/api/v1/teams/:teamId', logLevel: app.config.logging.http }) + } + await app.register(require('./mfa'), { prefix: '/api/v1', logLevel: app.config.logging.http }) + if (app.config.tables?.enabled) { + await app.register(require('./tables'), { prefix: '/api/v1/teams/:teamId/databases', logLevel: app.config.logging.http }) + } + await app.register(require('./resource'), { prefix: '/api/v1/projects/:instanceId/resources', logLevel: app.config.logging.http }) + await app.register(require('./autoUpdateStacks'), { prefix: '/api/v1/projects/:projectId/autoUpdateStack', logLevel: app.config.logging.http }) + await app.register(require('./httpTokens'), { prefix: '/api/v1', logLevel: app.config.logging.http }) + await app.register(require('./customHostnames'), { prefix: '/api/v1/projects/:projectId/customHostname', logLevel: app.config.logging.http }) + await app.register(require('./staticAssets'), { prefix: '/api/v1/projects/:projectId/files', logLevel: app.config.logging.http }) + await app.register(require('./projectHistory'), { prefix: '/api/v1/projects/:instanceId/history', logLevel: app.config.logging.http }) + await app.register(require('./deviceHistory'), { prefix: '/api/v1/devices/:deviceId/history', logLevel: app.config.logging.http }) +} + module.exports = async function (app) { app.addHook('preHandler', app.verifySession) if (app.config.billing) { await app.register(require('./billing'), { prefix: '/ee/billing', logLevel: app.config.logging.http }) } + // Features provied to any license level (inc pro) await app.register(require('./sharedLibrary'), { logLevel: app.config.logging.http }) await app.register(require('./pipeline'), { prefix: '/api/v1', logLevel: app.config.logging.http }) await app.register(require('./pipeline/teamPipelines.js'), { prefix: '/api/v1/teams/:teamId/pipelines', logLevel: app.config.logging.http }) @@ -19,31 +43,38 @@ module.exports = async function (app) { await app.register(require('./flowBlueprints'), { prefix: '/api/v1/flow-blueprints', logLevel: app.config.logging.http }) if (app.license.get('tier') === 'enterprise') { + await commonFeatures(app) await app.register(require('./applicationDeviceGroups'), { prefix: '/api/v1/applications/:applicationId/device-groups', logLevel: app.config.logging.http }) await app.register(require('./teamDeviceGroups'), { prefix: '/api/v1/teams/:teamId/device-groups', logLevel: app.config.logging.http }) await app.register(require('./ha'), { prefix: '/api/v1/projects/:projectId/ha', logLevel: app.config.logging.http }) await app.register(require('./protectedInstance'), { prefix: '/api/v1/projects/:projectId/protectInstance', logLevel: app.config.logging.http }) - await app.register(require('./mfa'), { prefix: '/api/v1', logLevel: app.config.logging.http }) - await app.register(require('./httpTokens'), { prefix: '/api/v1', logLevel: app.config.logging.http }) - await app.register(require('./customHostnames'), { prefix: '/api/v1/projects/:projectId/customHostname', logLevel: app.config.logging.http }) - await app.register(require('./staticAssets'), { prefix: '/api/v1/projects/:projectId/files', logLevel: app.config.logging.http }) - await app.register(require('./projectHistory'), { prefix: '/api/v1/projects/:instanceId/history', logLevel: app.config.logging.http }) - await app.register(require('./deviceHistory'), { prefix: '/api/v1/devices/:deviceId/history', logLevel: app.config.logging.http }) - await app.register(require('./teamBroker'), { prefix: '/api/v1/teams/:teamId/broker', logLevel: app.config.logging.http }) - await app.register(require('./teamBroker/3rdPartyBroker'), { prefix: '/api/v1/teams/:teamId/brokers', logLevel: app.config.logging.http }) - if (app.config.npmRegistry?.enabled) { - await app.register(require('./catalogues'), { prefix: '/api/v1/teams/:teamId', logLevel: app.config.logging.http }) - } await app.register(require('./gitops'), { prefix: '/api/v1/teams/:teamId/git', logLevel: app.config.logging.http }) - await app.register(require('./resource'), { prefix: '/api/v1/projects/:instanceId/resources', logLevel: app.config.logging.http }) - if (app.config.tables?.enabled) { - await app.register(require('./tables'), { prefix: '/api/v1/teams/:teamId/databases', logLevel: app.config.logging.http }) - } - await app.register(require('./mcp'), { logLevel: app.config.logging.http }) - await app.register(require('./autoUpdateStacks'), { prefix: '/api/v1/projects/:projectId/autoUpdateStack', logLevel: app.config.logging.http }) - await app.register(require('./expert'), { prefix: '/api/v1/expert', logLevel: app.config.logging.http }) + + // Important: keep SSO last to avoid its error handling polluting other routes. + await app.register(require('./sso'), { logLevel: app.config.logging.http }) + } else if (app.license.get('tier') === 'hub') { + await commonFeatures(app) + await app.register(require('./gitops'), { prefix: '/api/v1/teams/:teamId/git', logLevel: app.config.logging.http }) + await app.register(require('./ha'), { prefix: '/api/v1/projects/:projectId/ha', logLevel: app.config.logging.http }) + await app.register(require('./protectedInstance'), { prefix: '/api/v1/projects/:projectId/protectInstance', logLevel: app.config.logging.http }) + + // Important: keep SSO last to avoid its error handling polluting other routes. + await app.register(require('./sso'), { logLevel: app.config.logging.http }) + } else if (app.license.get('tier') === 'edge') { + await commonFeatures(app) + await app.register(require('./applicationDeviceGroups'), { prefix: '/api/v1/applications/:applicationId/device-groups', logLevel: app.config.logging.http }) + await app.register(require('./teamDeviceGroups'), { prefix: '/api/v1/teams/:teamId/device-groups', logLevel: app.config.logging.http }) + + // Important: keep SSO last to avoid its error handling polluting other routes. + await app.register(require('./sso'), { logLevel: app.config.logging.http }) + } else if (app.license.get('tier') === 'fleet') { + await commonFeatures(app) + await app.register(require('./applicationDeviceGroups'), { prefix: '/api/v1/applications/:applicationId/device-groups', logLevel: app.config.logging.http }) + await app.register(require('./teamDeviceGroups'), { prefix: '/api/v1/teams/:teamId/device-groups', logLevel: app.config.logging.http }) // Important: keep SSO last to avoid its error handling polluting other routes. await app.register(require('./sso'), { logLevel: app.config.logging.http }) + } else { + // old Pro license } } From 19a48bee7e375d6d558d96c554b7e8b9bbac8156 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Tue, 11 Aug 2026 17:02:24 +0100 Subject: [PATCH 2/9] Add new types file --- frontend/src/types/generated.ts | 1504 ++++++++++++++++++------------- 1 file changed, 870 insertions(+), 634 deletions(-) diff --git a/frontend/src/types/generated.ts b/frontend/src/types/generated.ts index b69f03e60b..dacbc44f7a 100644 --- a/frontend/src/types/generated.ts +++ b/frontend/src/types/generated.ts @@ -7984,44 +7984,32 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/flow-blueprints/import": { + "/api/v1/flow-blueprints/export-public": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; - put?: never; - /** Import one or more Blueprints */ - post: { + /** Export one or more Blueprints */ + get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - "application/json": { - blueprints: { - [key: string]: unknown; - }[]; - count?: number; - }; - }; - }; + requestBody?: never; responses: { /** @description Default Response */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { "application/json": { - blueprints?: components["schemas"]["FlowBlueprintSummary"][]; count?: number; - }; + } & components["schemas"]["FlowBlueprintExport"]; }; }; /** @description Default Response */ @@ -8035,79 +8023,38 @@ export interface paths { }; }; }; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/applications/{applicationId}/device-groups/": { + "/api/v1/flow-blueprints/import": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get a list of device groups in an application */ - get: { - parameters: { - query?: { - query?: string; - cursor?: string; - limit?: number; - page?: number; - sort?: string; - dir?: "asc" | "desc"; - order?: "asc" | "desc"; - }; - header?: never; - path: { - applicationId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Default Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - meta?: components["schemas"]["PaginationMeta"]; - count?: number; - groups?: components["schemas"]["DeviceGroupSummary"][]; - }; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; + get?: never; put?: never; - /** Add a new Device Group to an Application */ + /** Import one or more Blueprints */ post: { parameters: { query?: never; header?: never; - path: { - applicationId: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { "application/json": { - name: string; - description?: string; + blueprints: { + [key: string]: unknown; + }[]; + count?: number; }; }; }; @@ -8118,7 +8065,10 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["DeviceGroupSummary"]; + "application/json": { + blueprints?: components["schemas"]["FlowBlueprintSummary"][]; + count?: number; + }; }; }; /** @description Default Response */ @@ -8138,21 +8088,19 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/applications/{applicationId}/device-groups/{groupId}": { + "/api/v1/teams/{teamId}/mcp/": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get a specific Device Group */ get: { parameters: { query?: never; header?: never; path: { - applicationId: string; - groupId: string; + teamId: string; }; cookie?: never; }; @@ -8164,7 +8112,19 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["DeviceGroup"]; + "application/json": { + count?: number; + servers?: components["schemas"]["MCPRegistrationSummaryList"]; + }; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; }; }; /** @description Default Response */ @@ -8178,14 +8138,32 @@ export interface paths { }; }; }; - /** Update a Device Group */ - put: { + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/teams/{teamId}/mcp/{type}/{typeId}/{nodeId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: { parameters: { query?: never; header?: never; path: { - applicationId: string; - groupId: string; + teamId: string; + type: string; + typeId: string; + nodeId: string; }; cookie?: never; }; @@ -8193,8 +8171,11 @@ export interface paths { content: { "application/json": { name?: string; + endpointRoute?: string; + protocol?: string; + title?: string; + version?: string; description?: string; - targetSnapshotId?: string | null; }; }; }; @@ -8209,6 +8190,15 @@ export interface paths { }; }; /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ "4XX": { headers: { [name: string]: unknown; @@ -8219,15 +8209,15 @@ export interface paths { }; }; }; - post?: never; - /** Delete a Device Group */ delete: { parameters: { query?: never; header?: never; path: { - applicationId: string; - groupId: string; + teamId: string; + type: string; + typeId: string; + nodeId: string; }; cookie?: never; }; @@ -8243,6 +8233,15 @@ export interface paths { }; }; /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ "4XX": { headers: { [name: string]: unknown; @@ -8255,26 +8254,35 @@ export interface paths { }; options?: never; head?: never; - /** Update Device Group membership */ - patch: { + patch?: never; + trace?: never; + }; + "/api/v1/teams/{teamId}/broker/clients": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List MQTT clients for the team */ + get: { parameters: { - query?: never; + query?: { + query?: string; + cursor?: string; + limit?: number; + page?: number; + sort?: string; + dir?: "asc" | "desc"; + order?: "asc" | "desc"; + }; header?: never; path: { - applicationId: string; - groupId: string; + teamId: string; }; cookie?: never; }; - requestBody: { - content: { - "application/json": { - add?: string[]; - remove?: string[]; - set?: string[]; - }; - }; - }; + requestBody?: never; responses: { /** @description Default Response */ 200: { @@ -8282,7 +8290,22 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": Record; + "application/json": { + clients?: unknown[]; + meta?: components["schemas"]["PaginationMeta"]; + count?: number; + } & { + [key: string]: unknown; + }; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; }; }; /** @description Default Response */ @@ -8296,9 +8319,15 @@ export interface paths { }; }; }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; trace?: never; }; - "/api/v1/applications/{applicationId}/device-groups/{groupId}/settings": { + "/api/v1/teams/{teamId}/broker/client": { parameters: { query?: never; header?: never; @@ -8306,34 +8335,47 @@ export interface paths { cookie?: never; }; get?: never; - /** Update a Device Group Settings */ - put: { + put?: never; + /** Create new MQTT client for the team */ + post: { parameters: { query?: never; header?: never; path: { - applicationId: string; - groupId: string; + teamId: string; }; cookie?: never; }; requestBody: { content: { "application/json": { - env?: { - [key: string]: unknown; - }[]; + acls?: unknown[]; + username?: string; + password?: string; }; }; }; responses: { /** @description Default Response */ - 200: { + 201: { headers: { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["APIStatus"]; + "application/json": { + id?: string; + username?: string; + acls?: unknown[]; + }; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; }; }; /** @description Default Response */ @@ -8347,35 +8389,27 @@ export interface paths { }; }; }; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/device-groups/": { + "/api/v1/teams/{teamId}/broker/client/{username}": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get a list of device groups in an application */ + /** Get details about a specific MQTT client */ get: { parameters: { - query?: { - query?: string; - cursor?: string; - limit?: number; - page?: number; - sort?: string; - dir?: "asc" | "desc"; - order?: "asc" | "desc"; - }; + query?: never; header?: never; path: { - applicationId: string; + teamId: string; + username: string; }; cookie?: never; }; @@ -8388,13 +8422,28 @@ export interface paths { }; content: { "application/json": { - meta?: components["schemas"]["PaginationMeta"]; - count?: number; - groups?: components["schemas"]["DeviceGroupSummary"][]; + id?: string; + username?: string; + acls?: unknown[]; + owner?: null | { + /** @enum {string} */ + instanceType?: "instance" | "device"; + id?: string; + name?: string; + }; }; }; }; /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ "4XX": { headers: { [name: string]: unknown; @@ -8405,28 +8454,72 @@ export interface paths { }; }; }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/projects/{projectId}/files/_/{path}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; + /** Modify a MQTT Client */ + put: { + parameters: { + query?: never; + header?: never; + path: { + teamId: string; + username: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + password?: string; + acls?: unknown[]; + } | { + password?: string; + } | { + acls?: unknown[]; + }; + }; + }; + responses: { + /** @description Default Response */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + id?: string; + username?: string; + acls?: unknown[]; + }; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ + "4XX": { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; }; - /** List files stored in the instance */ - get: { + post?: never; + /** Delete a MQTT client */ + delete: { parameters: { query?: never; header?: never; path: { - instanceId: string; + teamId: string; + username: string; }; cookie?: never; }; @@ -8437,28 +8530,70 @@ export interface paths { headers: { [name: string]: unknown; }; - content?: never; + content: { + "application/json": components["schemas"]["APIStatus"]; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ + "4XX": { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; }; }; }; - /** Update file properties in the instance */ - put: { + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/teams/{teamId}/broker/client/{username}/link": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Link a MQTT client to a device or project */ + post: { parameters: { query?: never; header?: never; path: { - instanceId: string; + teamId: string; + username: string; }; cookie?: never; }; requestBody: { content: { "application/json": { - path?: string; - share?: { - [key: string]: unknown; - }; - }; + /** @enum {string} */ + ownerType?: "device" | "instance"; + ownerId?: string; + password?: string; + } & ({ + password: string; + } | { + /** @enum {string} */ + ownerType: "device" | "instance"; + ownerId: string; + password?: string; + }); }; }; responses: { @@ -8467,76 +8602,76 @@ export interface paths { headers: { [name: string]: unknown; }; - content?: never; - }; - }; - }; - /** Upload a file to the instance/Create directory */ - post: { - parameters: { - query?: never; - header?: never; - path: { - instanceId: string; + content: { + "application/json": { + id?: string; + username?: string; + acls?: unknown[]; + owner?: { + /** @enum {string} */ + type?: "instance" | "device"; + id?: string; + name?: string; + }; + }; + }; + }; + /** @description Default Response */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + id?: string; + username?: string; + acls?: unknown[]; + owner?: { + /** @enum {string} */ + instanceType?: "instance" | "device"; + id?: string; + name?: string; + }; + }; + }; }; - cookie?: never; - }; - requestBody?: never; - responses: { /** @description Default Response */ - 200: { + 500: { headers: { [name: string]: unknown; }; - content?: never; - }; - }; - }; - /** Delete a file in the instance */ - delete: { - parameters: { - query?: never; - header?: never; - path: { - instanceId: string; + content: { + "application/json": components["schemas"]["APIError"]; + }; }; - cookie?: never; - }; - requestBody?: never; - responses: { /** @description Default Response */ - 200: { + "4XX": { headers: { [name: string]: unknown; }; - content?: never; + content: { + "application/json": components["schemas"]["APIError"]; + }; }; }; }; + delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/broker/clients": { + "/api/v1/teams/{teamId}/brokers": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List MQTT clients for the team */ + /** Get credentials for 3rd party MQTT brokers */ get: { parameters: { - query?: { - query?: string; - cursor?: string; - limit?: number; - page?: number; - sort?: string; - dir?: "asc" | "desc"; - order?: "asc" | "desc"; - }; + query?: never; header?: never; path: { teamId: string; @@ -8552,9 +8687,9 @@ export interface paths { }; content: { "application/json": { - clients?: unknown[]; meta?: components["schemas"]["PaginationMeta"]; count?: number; + brokers?: components["schemas"]["MQTTBroker"][]; } & { [key: string]: unknown; }; @@ -8581,53 +8716,84 @@ export interface paths { }; }; put?: never; - post?: never; + /** Create credentials for a 3rd party MQTT broker */ + post: { + parameters: { + query?: never; + header?: never; + path: { + teamId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["MQTTBrokerInput"]; + }; + }; + responses: { + /** @description Default Response */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MQTTBroker"]; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ + "4XX": { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/broker/client": { + "/api/v1/teams/{teamId}/brokers/{brokerId}/credentials": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; - put?: never; - /** Create new MQTT client for the team */ - post: { + /** Gets credentials for a 3rd party MQTT broker */ + get: { parameters: { query?: never; header?: never; path: { teamId: string; + brokerId: string; }; cookie?: never; }; - requestBody: { - content: { - "application/json": { - acls?: unknown[]; - username?: string; - password?: string; - }; - }; - }; + requestBody?: never; responses: { /** @description Default Response */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - "application/json": { - id?: string; - username?: string; - acls?: unknown[]; - }; + "application/json": components["schemas"]["MQTTBroker"]; }; }; /** @description Default Response */ @@ -8650,27 +8816,29 @@ export interface paths { }; }; }; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/broker/client/{username}": { + "/api/v1/teams/{teamId}/brokers/{brokerId}": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get details about a specific MQTT client */ + /** Get 3rd Party Broker details and status */ get: { parameters: { query?: never; header?: never; path: { teamId: string; - username: string; + brokerId: string; }; cookie?: never; }; @@ -8682,16 +8850,8 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": { - id?: string; - username?: string; - acls?: unknown[]; - owner?: null | { - /** @enum {string} */ - instanceType?: "instance" | "device"; - id?: string; - name?: string; - }; + "application/json": components["schemas"]["MQTTBroker"] | { + state: string; }; }; }; @@ -8715,41 +8875,30 @@ export interface paths { }; }; }; - /** Modify a MQTT Client */ + /** Delete credentials for a 3rd party MQTT broker */ put: { parameters: { query?: never; header?: never; path: { teamId: string; - username: string; + brokerId: string; }; cookie?: never; }; requestBody: { content: { - "application/json": { - password?: string; - acls?: unknown[]; - } | { - password?: string; - } | { - acls?: unknown[]; - }; + "application/json": components["schemas"]["MQTTBrokerInput"]; }; }; responses: { /** @description Default Response */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - "application/json": { - id?: string; - username?: string; - acls?: unknown[]; - }; + "application/json": components["schemas"]["MQTTBroker"]; }; }; /** @description Default Response */ @@ -8773,14 +8922,14 @@ export interface paths { }; }; post?: never; - /** Delete a MQTT client */ + /** Delete credentials for a 3rd party MQTT broker */ delete: { parameters: { query?: never; header?: never; path: { teamId: string; - username: string; + brokerId: string; }; cookie?: never; }; @@ -8792,7 +8941,9 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["APIStatus"]; + "application/json": { + [key: string]: unknown; + }; }; }; /** @description Default Response */ @@ -8820,43 +8971,24 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/broker/client/{username}/link": { + "/api/v1/teams/{teamId}/brokers/{brokerId}/topics": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; - put?: never; - /** Link a MQTT client to a device or project */ - post: { + get: { parameters: { query?: never; header?: never; path: { teamId: string; - username: string; + brokerId: string; }; cookie?: never; }; - requestBody: { - content: { - "application/json": { - /** @enum {string} */ - ownerType?: "device" | "instance"; - ownerId?: string; - password?: string; - } & ({ - password: string; - } | { - /** @enum {string} */ - ownerType: "device" | "instance"; - ownerId: string; - password?: string; - }); - }; - }; + requestBody?: never; responses: { /** @description Default Response */ 200: { @@ -8865,34 +8997,54 @@ export interface paths { }; content: { "application/json": { - id?: string; - username?: string; - acls?: unknown[]; - owner?: { - /** @enum {string} */ - type?: "instance" | "device"; - id?: string; - name?: string; - }; + [key: string]: unknown; }; }; }; /** @description Default Response */ - 201: { + 500: { headers: { [name: string]: unknown; }; content: { - "application/json": { - id?: string; - username?: string; - acls?: unknown[]; - owner?: { - /** @enum {string} */ - instanceType?: "instance" | "device"; - id?: string; - name?: string; - }; + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ + "4XX": { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + put?: never; + /** Store Topics from a 3rd party MQTT broker */ + post: { + parameters: { + query?: never; + header?: never; + path: { + teamId: string; + brokerId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Default Response */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + topic?: string; + } & { + [key: string]: unknown; }; }; }; @@ -8922,36 +9074,34 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/brokers": { + "/api/v1/teams/{teamId}/brokers/{brokerId}/topics/{topicId}": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get credentials for 3rd party MQTT brokers */ - get: { + get?: never; + put: { parameters: { query?: never; header?: never; path: { teamId: string; + brokerId: string; + topicId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Default Response */ - 200: { + 201: { headers: { [name: string]: unknown; }; content: { "application/json": { - meta?: components["schemas"]["PaginationMeta"]; - count?: number; - brokers?: components["schemas"]["MQTTBroker"][]; - } & { [key: string]: unknown; }; }; @@ -8976,22 +9126,19 @@ export interface paths { }; }; }; - put?: never; - /** Create credentials for a 3rd party MQTT broker */ - post: { + post?: never; + delete: { parameters: { query?: never; header?: never; path: { teamId: string; + brokerId: string; + topicId: string; }; cookie?: never; }; - requestBody: { - content: { - "application/json": components["schemas"]["MQTTBrokerInput"]; - }; - }; + requestBody?: never; responses: { /** @description Default Response */ 201: { @@ -8999,7 +9146,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["MQTTBroker"]; + "application/json": Record; }; }; /** @description Default Response */ @@ -9022,27 +9169,25 @@ export interface paths { }; }; }; - delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/brokers/{brokerId}/credentials": { + "/api/v1/teams/{teamId}/npm/packages": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Gets credentials for a 3rd party MQTT broker */ + /** Gets the private packages owned by this team */ get: { parameters: { query?: never; header?: never; path: { teamId: string; - brokerId: string; }; cookie?: never; }; @@ -9053,27 +9198,7 @@ export interface paths { headers: { [name: string]: unknown; }; - content: { - "application/json": components["schemas"]["MQTTBroker"]; - }; - }; - /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; + content?: never; }; }; }; @@ -9085,44 +9210,47 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/brokers/{brokerId}": { + "/api/v1/teams/{teamId}/npm/subflow": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get 3rd Party Broker details and status */ - get: { + get?: never; + /** Allows Subflow packages to be stored in the Team Registry */ + put: { parameters: { query?: never; header?: never; path: { teamId: string; - brokerId: string; }; cookie?: never; }; - requestBody?: never; - responses: { - /** @description Default Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MQTTBroker"] | { - state: string; + requestBody: { + content: { + "application/json": { + package?: { + name: string; + version: string; + } & { + [key: string]: unknown; + }; + subflow?: { + [key: string]: unknown; }; }; }; + }; + responses: { /** @description Default Response */ - 500: { + 200: { headers: { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["APIError"]; + "application/json": Record; }; }; /** @description Default Response */ @@ -9136,22 +9264,32 @@ export interface paths { }; }; }; - /** Delete credentials for a 3rd party MQTT broker */ - put: { + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/teams/{teamId}/npm/userToken": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Check if user already has a NPM auth token */ + get: { parameters: { query?: never; header?: never; path: { teamId: string; - brokerId: string; + userId: string; }; cookie?: never; }; - requestBody: { - content: { - "application/json": components["schemas"]["MQTTBrokerInput"]; - }; - }; + requestBody?: never; responses: { /** @description Default Response */ 200: { @@ -9159,16 +9297,16 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["MQTTBroker"]; + "application/json": Record; }; }; /** @description Default Response */ - 500: { + 404: { headers: { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["APIError"]; + "application/json": Record; }; }; /** @description Default Response */ @@ -9182,41 +9320,33 @@ export interface paths { }; }; }; - post?: never; - /** Delete credentials for a 3rd party MQTT broker */ - delete: { + put?: never; + /** Generate a new user password for NPM registry */ + post: { parameters: { query?: never; header?: never; path: { teamId: string; - brokerId: string; + userId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Default Response */ - 200: { + 201: { headers: { [name: string]: unknown; }; content: { "application/json": { - [key: string]: unknown; + username?: string; + token?: string; }; }; }; /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Default Response */ "4XX": { headers: { [name: string]: unknown; @@ -9227,12 +9357,13 @@ export interface paths { }; }; }; + delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/brokers/{brokerId}/topics": { + "/api/v1/teams/{teamId}/databases/": { parameters: { query?: never; header?: never; @@ -9245,7 +9376,6 @@ export interface paths { header?: never; path: { teamId: string; - brokerId: string; }; cookie?: never; }; @@ -9257,9 +9387,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": { - [key: string]: unknown; - }; + "application/json": components["schemas"]["DatabaseCredentials"][]; }; }; /** @description Default Response */ @@ -9283,30 +9411,31 @@ export interface paths { }; }; put?: never; - /** Store Topics from a 3rd party MQTT broker */ post: { parameters: { query?: never; header?: never; path: { teamId: string; - brokerId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": { + /** @description Name of the database */ + name?: string; + }; + }; + }; responses: { /** @description Default Response */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - "application/json": { - topic?: string; - } & { - [key: string]: unknown; - }; + "application/json": components["schemas"]["DatabaseCredentials"]; }; }; /** @description Default Response */ @@ -9335,36 +9464,31 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/brokers/{brokerId}/topics/{topicId}": { + "/api/v1/teams/{teamId}/databases/{databaseId}": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; - put: { + get: { parameters: { query?: never; header?: never; path: { - teamId: string; - brokerId: string; - topicId: string; + databaseId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Default Response */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - "application/json": { - [key: string]: unknown; - }; + "application/json": components["schemas"]["DatabaseCredentials"]; }; }; /** @description Default Response */ @@ -9387,27 +9511,26 @@ export interface paths { }; }; }; + put?: never; post?: never; delete: { parameters: { query?: never; header?: never; path: { - teamId: string; - brokerId: string; - topicId: string; + databaseId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Default Response */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - "application/json": Record; + "application/json": unknown; }; }; /** @description Default Response */ @@ -9435,24 +9558,88 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/projects/{instanceId}/resources/": { + "/api/v1/teams/{teamId}/databases/{databaseId}/tables": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Returns resource usage history for an Instance */ - get: { + get: { + parameters: { + query?: { + query?: string; + cursor?: string; + limit?: number; + page?: number; + sort?: string; + dir?: "asc" | "desc"; + order?: "asc" | "desc"; + }; + header?: never; + path: { + databaseId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Default Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + count?: number; + tables?: { + name?: string; + schema?: string; + }[]; + meta?: { + [key: string]: unknown; + }; + }; + }; + }; + /** @description Default Response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Default Response */ + "4XX": { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + put?: never; + post: { parameters: { query?: never; header?: never; path: { - instanceId: string; + databaseId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": { + name?: string; + columns?: components["schemas"]["DatabaseTable"]; + }; + }; + }; responses: { /** @description Default Response */ 200: { @@ -9460,18 +9647,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": { - meta?: components["schemas"]["PaginationMeta"]; - resources?: { - src?: string; - ps?: number; - cpu?: number; - hs?: number; - hu?: number; - ts?: number; - }[]; - count?: number; - }; + "application/json": components["schemas"]["DatabaseTable"]; }; }; /** @description Default Response */ @@ -9494,15 +9670,13 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/databases/": { + "/api/v1/teams/{teamId}/databases/{databaseId}/tables/{tableName}/{schemaName}?": { parameters: { query?: never; header?: never; @@ -9514,7 +9688,9 @@ export interface paths { query?: never; header?: never; path: { - teamId: string; + databaseId: string; + tableName: string; + schemaName: string; }; cookie?: never; }; @@ -9526,7 +9702,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["DatabaseCredentials"][]; + "application/json": components["schemas"]["DatabaseTable"]; }; }; /** @description Default Response */ @@ -9550,23 +9726,19 @@ export interface paths { }; }; put?: never; - post: { + post?: never; + delete: { parameters: { query?: never; header?: never; path: { - teamId: string; + databaseId: string; + tableName: string; + schemaName: string; }; cookie?: never; }; - requestBody: { - content: { - "application/json": { - /** @description Name of the database */ - name?: string; - }; - }; - }; + requestBody?: never; responses: { /** @description Default Response */ 200: { @@ -9574,7 +9746,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["DatabaseCredentials"]; + "application/json": components["schemas"]["DatabaseTable"]; }; }; /** @description Default Response */ @@ -9597,13 +9769,12 @@ export interface paths { }; }; }; - delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/databases/{databaseId}": { + "/api/v1/teams/{teamId}/databases/{databaseId}/tables/{tableName}/data/{schemaName}?": { parameters: { query?: never; header?: never; @@ -9612,10 +9783,20 @@ export interface paths { }; get: { parameters: { - query?: never; + query?: { + query?: string; + cursor?: string; + limit?: number; + page?: number; + sort?: string; + dir?: "asc" | "desc"; + order?: "asc" | "desc"; + }; header?: never; path: { databaseId: string; + tableName: string; + schemaName: string; }; cookie?: never; }; @@ -9627,7 +9808,15 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["DatabaseCredentials"]; + "application/json": { + count?: number; + rows?: { + [key: string]: unknown; + }[]; + meta?: { + [key: string]: unknown; + }; + }; }; }; /** @description Default Response */ @@ -9652,12 +9841,26 @@ export interface paths { }; put?: never; post?: never; - delete: { + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/projects/{instanceId}/resources/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Returns resource usage history for an Instance */ + get: { parameters: { query?: never; header?: never; path: { - databaseId: string; + instanceId: string; }; cookie?: never; }; @@ -9669,7 +9872,18 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": unknown; + "application/json": { + meta?: components["schemas"]["PaginationMeta"]; + resources?: { + src?: string; + ps?: number; + cpu?: number; + hs?: number; + hu?: number; + ts?: number; + }[]; + count?: number; + }; }; }; /** @description Default Response */ @@ -9692,32 +9906,28 @@ export interface paths { }; }; }; + put?: never; + post?: never; + delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/databases/{databaseId}/tables": { + "/api/v1/projects/{projectId}/autoUpdateStack/": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; + /** Returns when a Instance allowed to be restarted */ get: { parameters: { - query?: { - query?: string; - cursor?: string; - limit?: number; - page?: number; - sort?: string; - dir?: "asc" | "desc"; - order?: "asc" | "desc"; - }; + query?: never; header?: never; path: { - databaseId: string; + projectId: string; }; cookie?: never; }; @@ -9730,24 +9940,10 @@ export interface paths { }; content: { "application/json": { - count?: number; - tables?: { - name?: string; - schema?: string; - }[]; - meta?: { - [key: string]: unknown; - }; - }; - }; - }; - /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; + hour?: number; + day?: number; + restart?: boolean; + }[]; }; }; /** @description Default Response */ @@ -9761,21 +9957,24 @@ export interface paths { }; }; }; - put?: never; - post: { + /** Sets when an Instance can be restarted */ + put: { parameters: { query?: never; header?: never; path: { - databaseId: string; + projectId: string; }; cookie?: never; }; requestBody: { content: { "application/json": { - name?: string; - columns?: components["schemas"]["DatabaseTable"]; + schedule?: { + hour?: number; + day?: number; + restart?: boolean; + }[]; }; }; }; @@ -9786,11 +9985,15 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["DatabaseTable"]; + "application/json": { + hour?: number; + day?: number; + restart?: boolean; + }[]; }; }; /** @description Default Response */ - 500: { + "4XX": { headers: { [name: string]: unknown; }; @@ -9798,6 +10001,30 @@ export interface paths { "application/json": components["schemas"]["APIError"]; }; }; + }; + }; + post?: never; + /** Clears when an Instance can be restarted */ + delete: { + parameters: { + query?: never; + header?: never; + path: { + projectId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Default Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; /** @description Default Response */ "4XX": { headers: { @@ -9809,27 +10036,25 @@ export interface paths { }; }; }; - delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/databases/{databaseId}/tables/{tableName}/{schemaName}?": { + "/api/v1/projects/{projectId}/files/_/{path}": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; + /** List files stored in the instance */ get: { parameters: { query?: never; header?: never; path: { - databaseId: string; - tableName: string; - schemaName: string; + instanceId: string; }; cookie?: never; }; @@ -9840,40 +10065,68 @@ export interface paths { headers: { [name: string]: unknown; }; - content: { - "application/json": components["schemas"]["DatabaseTable"]; + content?: never; + }; + }; + }; + /** Update file properties in the instance */ + put: { + parameters: { + query?: never; + header?: never; + path: { + instanceId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + path?: string; + share?: { + [key: string]: unknown; + }; }; }; + }; + responses: { /** @description Default Response */ - 500: { + 200: { headers: { [name: string]: unknown; }; - content: { - "application/json": components["schemas"]["APIError"]; - }; + content?: never; + }; + }; + }; + /** Upload a file to the instance/Create directory */ + post: { + parameters: { + query?: never; + header?: never; + path: { + instanceId: string; }; + cookie?: never; + }; + requestBody?: never; + responses: { /** @description Default Response */ - "4XX": { + 200: { headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; + [name: string]: unknown; }; + content?: never; }; }; }; - put?: never; - post?: never; + /** Delete a file in the instance */ delete: { parameters: { query?: never; header?: never; path: { - databaseId: string; - tableName: string; - schemaName: string; + instanceId: string; }; cookie?: never; }; @@ -9884,27 +10137,7 @@ export interface paths { headers: { [name: string]: unknown; }; - content: { - "application/json": components["schemas"]["DatabaseTable"]; - }; - }; - /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; + content?: never; }; }; }; @@ -9913,13 +10146,14 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/databases/{databaseId}/tables/{tableName}/data/{schemaName}?": { + "/api/v1/applications/{applicationId}/device-groups/": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; + /** Get a list of device groups in an application */ get: { parameters: { query?: { @@ -9933,9 +10167,7 @@ export interface paths { }; header?: never; path: { - databaseId: string; - tableName: string; - schemaName: string; + applicationId: string; }; cookie?: never; }; @@ -9948,18 +10180,14 @@ export interface paths { }; content: { "application/json": { + meta?: components["schemas"]["PaginationMeta"]; count?: number; - rows?: { - [key: string]: unknown; - }[]; - meta?: { - [key: string]: unknown; - }; + groups?: components["schemas"]["DeviceGroupSummary"][]; }; }; }; /** @description Default Response */ - 500: { + "4XX": { headers: { [name: string]: unknown; }; @@ -9967,6 +10195,37 @@ export interface paths { "application/json": components["schemas"]["APIError"]; }; }; + }; + }; + put?: never; + /** Add a new Device Group to an Application */ + post: { + parameters: { + query?: never; + header?: never; + path: { + applicationId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + name: string; + description?: string; + }; + }; + }; + responses: { + /** @description Default Response */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DeviceGroupSummary"]; + }; + }; /** @description Default Response */ "4XX": { headers: { @@ -9978,27 +10237,27 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/mcp/": { + "/api/v1/applications/{applicationId}/device-groups/{groupId}": { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; + /** Get a specific Device Group */ get: { parameters: { query?: never; header?: never; path: { - teamId: string; + applicationId: string; + groupId: string; }; cookie?: never; }; @@ -10010,19 +10269,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": { - count?: number; - servers?: components["schemas"]["MCPRegistrationSummaryList"]; - }; - }; - }; - /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; + "application/json": components["schemas"]["DeviceGroup"]; }; }; /** @description Default Response */ @@ -10036,32 +10283,14 @@ export interface paths { }; }; }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/teams/{teamId}/mcp/{type}/{typeId}/{nodeId}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post: { + /** Update a Device Group */ + put: { parameters: { query?: never; header?: never; path: { - teamId: string; - type: string; - typeId: string; - nodeId: string; + applicationId: string; + groupId: string; }; cookie?: never; }; @@ -10069,11 +10298,8 @@ export interface paths { content: { "application/json": { name?: string; - endpointRoute?: string; - protocol?: string; - title?: string; - version?: string; description?: string; + targetSnapshotId?: string | null; }; }; }; @@ -10088,15 +10314,6 @@ export interface paths { }; }; /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Default Response */ "4XX": { headers: { [name: string]: unknown; @@ -10107,15 +10324,15 @@ export interface paths { }; }; }; + post?: never; + /** Delete a Device Group */ delete: { parameters: { query?: never; header?: never; path: { - teamId: string; - type: string; - typeId: string; - nodeId: string; + applicationId: string; + groupId: string; }; cookie?: never; }; @@ -10131,15 +10348,6 @@ export interface paths { }; }; /** @description Default Response */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Default Response */ "4XX": { headers: { [name: string]: unknown; @@ -10152,27 +10360,26 @@ export interface paths { }; options?: never; head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/projects/{projectId}/autoUpdateStack/": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Returns when a Instance allowed to be restarted */ - get: { + /** Update Device Group membership */ + patch: { parameters: { query?: never; header?: never; path: { - projectId: string; + applicationId: string; + groupId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": { + add?: string[]; + remove?: string[]; + set?: string[]; + }; + }; + }; responses: { /** @description Default Response */ 200: { @@ -10180,11 +10387,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": { - hour?: number; - day?: number; - restart?: boolean; - }[]; + "application/json": Record; }; }; /** @description Default Response */ @@ -10198,23 +10401,32 @@ export interface paths { }; }; }; - /** Sets when an Instance can be restarted */ + trace?: never; + }; + "/api/v1/applications/{applicationId}/device-groups/{groupId}/settings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** Update a Device Group Settings */ put: { parameters: { query?: never; header?: never; path: { - projectId: string; + applicationId: string; + groupId: string; }; cookie?: never; }; requestBody: { content: { "application/json": { - schedule?: { - hour?: number; - day?: number; - restart?: boolean; + env?: { + [key: string]: unknown; }[]; }; }; @@ -10226,11 +10438,7 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": { - hour?: number; - day?: number; - restart?: boolean; - }[]; + "application/json": components["schemas"]["APIStatus"]; }; }; /** @description Default Response */ @@ -10245,13 +10453,34 @@ export interface paths { }; }; post?: never; - /** Clears when an Instance can be restarted */ - delete: { + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/teams/{teamId}/device-groups/": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get a list of device groups in an application */ + get: { parameters: { - query?: never; + query?: { + query?: string; + cursor?: string; + limit?: number; + page?: number; + sort?: string; + dir?: "asc" | "desc"; + order?: "asc" | "desc"; + }; header?: never; path: { - projectId: string; + applicationId: string; }; cookie?: never; }; @@ -10263,7 +10492,11 @@ export interface paths { [name: string]: unknown; }; content: { - "application/json": unknown; + "application/json": { + meta?: components["schemas"]["PaginationMeta"]; + count?: number; + groups?: components["schemas"]["DeviceGroupSummary"][]; + }; }; }; /** @description Default Response */ @@ -10277,6 +10510,9 @@ export interface paths { }; }; }; + put?: never; + post?: never; + delete?: never; options?: never; head?: never; patch?: never; From 2a0e8d746b0d28f5291ea594e47fcc8ac2f78c0a Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Tue, 11 Aug 2026 17:05:33 +0100 Subject: [PATCH 3/9] remove duplicate sso enablement --- forge/ee/routes/index.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/forge/ee/routes/index.js b/forge/ee/routes/index.js index 1c3a967657..b20497d714 100644 --- a/forge/ee/routes/index.js +++ b/forge/ee/routes/index.js @@ -42,6 +42,8 @@ module.exports = async function (app) { await app.register(require('./flowBlueprints'), { prefix: '/api/v1/flow-blueprints', logLevel: app.config.logging.http }) + let enableSSO = false + if (app.license.get('tier') === 'enterprise') { await commonFeatures(app) await app.register(require('./applicationDeviceGroups'), { prefix: '/api/v1/applications/:applicationId/device-groups', logLevel: app.config.logging.http }) @@ -50,31 +52,32 @@ module.exports = async function (app) { await app.register(require('./protectedInstance'), { prefix: '/api/v1/projects/:projectId/protectInstance', logLevel: app.config.logging.http }) await app.register(require('./gitops'), { prefix: '/api/v1/teams/:teamId/git', logLevel: app.config.logging.http }) - // Important: keep SSO last to avoid its error handling polluting other routes. - await app.register(require('./sso'), { logLevel: app.config.logging.http }) + enableSSO = true } else if (app.license.get('tier') === 'hub') { await commonFeatures(app) await app.register(require('./gitops'), { prefix: '/api/v1/teams/:teamId/git', logLevel: app.config.logging.http }) await app.register(require('./ha'), { prefix: '/api/v1/projects/:projectId/ha', logLevel: app.config.logging.http }) await app.register(require('./protectedInstance'), { prefix: '/api/v1/projects/:projectId/protectInstance', logLevel: app.config.logging.http }) - // Important: keep SSO last to avoid its error handling polluting other routes. - await app.register(require('./sso'), { logLevel: app.config.logging.http }) + enableSSO = true } else if (app.license.get('tier') === 'edge') { await commonFeatures(app) await app.register(require('./applicationDeviceGroups'), { prefix: '/api/v1/applications/:applicationId/device-groups', logLevel: app.config.logging.http }) await app.register(require('./teamDeviceGroups'), { prefix: '/api/v1/teams/:teamId/device-groups', logLevel: app.config.logging.http }) - // Important: keep SSO last to avoid its error handling polluting other routes. - await app.register(require('./sso'), { logLevel: app.config.logging.http }) + enableSSO = true } else if (app.license.get('tier') === 'fleet') { await commonFeatures(app) await app.register(require('./applicationDeviceGroups'), { prefix: '/api/v1/applications/:applicationId/device-groups', logLevel: app.config.logging.http }) await app.register(require('./teamDeviceGroups'), { prefix: '/api/v1/teams/:teamId/device-groups', logLevel: app.config.logging.http }) - // Important: keep SSO last to avoid its error handling polluting other routes. - await app.register(require('./sso'), { logLevel: app.config.logging.http }) + enableSSO = true } else { // old Pro license } + + if (enableSSO) { + // Important: keep SSO last to avoid its error handling polluting other routes. + await app.register(require('./sso'), { logLevel: app.config.logging.http }) + } } From b0eda62b185a745dd1008bee1e223a8420709add Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Tue, 11 Aug 2026 17:29:59 +0100 Subject: [PATCH 4/9] Second attempt at types --- frontend/src/types/generated.ts | 236 -------------------------------- 1 file changed, 236 deletions(-) diff --git a/frontend/src/types/generated.ts b/frontend/src/types/generated.ts index dacbc44f7a..a63dbffabe 100644 --- a/frontend/src/types/generated.ts +++ b/frontend/src/types/generated.ts @@ -7984,53 +7984,6 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/flow-blueprints/export-public": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Export one or more Blueprints */ - get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Default Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - count?: number; - } & components["schemas"]["FlowBlueprintExport"]; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/api/v1/flow-blueprints/import": { parameters: { query?: never; @@ -9174,195 +9127,6 @@ export interface paths { patch?: never; trace?: never; }; - "/api/v1/teams/{teamId}/npm/packages": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Gets the private packages owned by this team */ - get: { - parameters: { - query?: never; - header?: never; - path: { - teamId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Default Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/teams/{teamId}/npm/subflow": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - /** Allows Subflow packages to be stored in the Team Registry */ - put: { - parameters: { - query?: never; - header?: never; - path: { - teamId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": { - package?: { - name: string; - version: string; - } & { - [key: string]: unknown; - }; - subflow?: { - [key: string]: unknown; - }; - }; - }; - }; - responses: { - /** @description Default Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": Record; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/teams/{teamId}/npm/userToken": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Check if user already has a NPM auth token */ - get: { - parameters: { - query?: never; - header?: never; - path: { - teamId: string; - userId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Default Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": Record; - }; - }; - /** @description Default Response */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": Record; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - put?: never; - /** Generate a new user password for NPM registry */ - post: { - parameters: { - query?: never; - header?: never; - path: { - teamId: string; - userId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Default Response */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - username?: string; - token?: string; - }; - }; - }; - /** @description Default Response */ - "4XX": { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/api/v1/teams/{teamId}/databases/": { parameters: { query?: never; From 0c54bd1e6b38c08eee1f3afcd8c119449614fdce Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Tue, 11 Aug 2026 17:52:15 +0100 Subject: [PATCH 5/9] fix lint --- forge/ee/lib/index.js | 6 +----- forge/ee/routes/index.js | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/forge/ee/lib/index.js b/forge/ee/lib/index.js index 81ca1f0b92..e1a3e9241b 100644 --- a/forge/ee/lib/index.js +++ b/forge/ee/lib/index.js @@ -1,7 +1,7 @@ const fp = require('fastify-plugin') // common features across all higher tier (enterpise, hub, edge, fleet) -async function commonFeatures(app, opts) { +async function commonFeatures (app, opts) { app.decorate('sso', await require('./sso').init(app)) await require('./teamBroker').init(app) // Set the MFA Feature Flag @@ -72,7 +72,6 @@ module.exports = fp(async function (app, opts) { // Set the Device Groups Feature Flag app.config.features.register('deviceGroups', true, true) - } else if (app.license.get('tier') === 'hub') { await commonFeatures(app, opts) // HA @@ -81,17 +80,14 @@ module.exports = fp(async function (app, opts) { require('./protectedInstance').init(app) // Git Opps app.decorate('gitops', await require('./gitops').init(app)) - } else if (app.license.get('tier') === 'edge') { await commonFeatures(app, opts) // Set the Device Groups Feature Flag app.config.features.register('deviceGroups', true, true) - } else if (app.license.get('tier') === 'fleet') { await commonFeatures(app, opts) // Set the Device Groups Feature Flag app.config.features.register('deviceGroups', true, true) - } else { // old "Pro" license } diff --git a/forge/ee/routes/index.js b/forge/ee/routes/index.js index b20497d714..e3a9b1227e 100644 --- a/forge/ee/routes/index.js +++ b/forge/ee/routes/index.js @@ -6,7 +6,7 @@ */ // common features across all higher tier (enterpise, hub, edge, fleet) -async function commonFeatures(app) { +async function commonFeatures (app) { await app.register(require('./expert'), { prefix: '/api/v1/expert', logLevel: app.config.logging.http }) await app.register(require('./mcp'), { logLevel: app.config.logging.http }) await app.register(require('./teamBroker'), { prefix: '/api/v1/teams/:teamId/broker', logLevel: app.config.logging.http }) From 7abb6e0c0a453aed32d1e03bb34e1972771d3469 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Tue, 11 Aug 2026 19:53:27 +0100 Subject: [PATCH 6/9] more lint --- forge/ee/routes/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/ee/routes/index.js b/forge/ee/routes/index.js index e3a9b1227e..59d39840ee 100644 --- a/forge/ee/routes/index.js +++ b/forge/ee/routes/index.js @@ -51,7 +51,7 @@ module.exports = async function (app) { await app.register(require('./ha'), { prefix: '/api/v1/projects/:projectId/ha', logLevel: app.config.logging.http }) await app.register(require('./protectedInstance'), { prefix: '/api/v1/projects/:projectId/protectInstance', logLevel: app.config.logging.http }) await app.register(require('./gitops'), { prefix: '/api/v1/teams/:teamId/git', logLevel: app.config.logging.http }) - + enableSSO = true } else if (app.license.get('tier') === 'hub') { await commonFeatures(app) From 09a9065a1c92acbb80a8054dfca1b3c6dcc68156 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Wed, 12 Aug 2026 09:15:58 +0100 Subject: [PATCH 7/9] Add new license levels --- forge/licensing/license-generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/licensing/license-generator.js b/forge/licensing/license-generator.js index fdd69dd655..904b7dd67e 100644 --- a/forge/licensing/license-generator.js +++ b/forge/licensing/license-generator.js @@ -54,7 +54,7 @@ const { v4: uuidv4 } = require('uuid') replace: '*' }) - const licenseTier = await promptly.choose('License tier (teams*, enterprise): ', ['teams', 'enterprise'], { default: 'teams', trim: true }) + const licenseTier = await promptly.choose('License tier (teams, enterprise, hub*, edge, fleet): ', ['teams', 'enterprise', 'hub', 'edge', 'fleet'], { default: 'hub', trim: true }) const licenseHolder = await promptly.prompt('License holder name: ') From 6c2c9b0a6d7e722519339fab893c94d3063c8f61 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Wed, 12 Aug 2026 09:52:53 +0100 Subject: [PATCH 8/9] re-sync package-lock --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 741955d732..b3463526d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14567,9 +14567,9 @@ } }, "node_modules/globals": { - "version": "17.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.9.0.tgz", - "integrity": "sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==", + "version": "17.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.10.0.tgz", + "integrity": "sha512-V0kztuWST2k8A/VbxAY8+L+7+Rgo3fyA24IHRLrZp7HOzJjV0gHSaZUjK9lpP/IrBSNite2tZ1prhRkinRu1CA==", "dev": true, "license": "MIT", "engines": { @@ -36292,9 +36292,9 @@ } }, "globals": { - "version": "17.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.9.0.tgz", - "integrity": "sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==", + "version": "17.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.10.0.tgz", + "integrity": "sha512-V0kztuWST2k8A/VbxAY8+L+7+Rgo3fyA24IHRLrZp7HOzJjV0gHSaZUjK9lpP/IrBSNite2tZ1prhRkinRu1CA==", "dev": true }, "globalthis": { From 2552609157681acdb6fa477148582bf17e551bc5 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Wed, 12 Aug 2026 13:46:46 +0100 Subject: [PATCH 9/9] resync package-lock.json --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3463526d3..17c5fa18cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14567,9 +14567,9 @@ } }, "node_modules/globals": { - "version": "17.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.10.0.tgz", - "integrity": "sha512-V0kztuWST2k8A/VbxAY8+L+7+Rgo3fyA24IHRLrZp7HOzJjV0gHSaZUjK9lpP/IrBSNite2tZ1prhRkinRu1CA==", + "version": "17.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.11.0.tgz", + "integrity": "sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==", "dev": true, "license": "MIT", "engines": { @@ -36292,9 +36292,9 @@ } }, "globals": { - "version": "17.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.10.0.tgz", - "integrity": "sha512-V0kztuWST2k8A/VbxAY8+L+7+Rgo3fyA24IHRLrZp7HOzJjV0gHSaZUjK9lpP/IrBSNite2tZ1prhRkinRu1CA==", + "version": "17.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.11.0.tgz", + "integrity": "sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==", "dev": true }, "globalthis": {