diff --git a/.gitignore b/.gitignore index b47b17f7fb..b796141e41 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,9 @@ vendor/bundle CLAUDE.local.md .env .idea/ +plugin-host/dist/ +plugin-host/node_modules/ +/plugins/ +*.spx +examples/plugins/superplane-plugin-github-issues/node_modules/ +examples/plugins/superplane-plugin-github-issues/dist/ diff --git a/Makefile b/Makefile index 5cc4234412..4e8592fdc1 100644 --- a/Makefile +++ b/Makefile @@ -149,6 +149,15 @@ check.build.ui: check.build.app: docker compose $(DOCKER_COMPOSE_OPTS) exec app go build cmd/server/main.go +# +# Plugin Host targets +# + +plugin-host.setup: + cd plugin-host && npm install + +plugin-host.build: + cd plugin-host && npm install && npm run build storybook: docker compose $(DOCKER_COMPOSE_OPTS) exec app /bin/bash -c "cd web_src && npm install && npm run storybook" @@ -227,8 +236,8 @@ gen.components.local.update: gen.components.docs rm -rf ../docs/src/content/docs/components cp -R docs/components ../docs/src/content/docs/components -MODULES := authorization,organizations,integrations,secrets,users,groups,roles,me,configuration,components,triggers,widgets,blueprints,canvases,service_accounts -REST_API_MODULES := authorization,organizations,integrations,secrets,users,groups,roles,me,configuration,components,triggers,widgets,blueprints,canvases,service_accounts +MODULES := authorization,organizations,integrations,secrets,users,groups,roles,me,configuration,components,triggers,widgets,blueprints,canvases,service_accounts,scripts +REST_API_MODULES := authorization,organizations,integrations,secrets,users,groups,roles,me,configuration,components,triggers,widgets,blueprints,canvases,service_accounts,scripts pb.gen: docker compose $(DOCKER_COMPOSE_OPTS) run --rm --no-deps app /app/scripts/protoc.sh $(MODULES) docker compose $(DOCKER_COMPOSE_OPTS) run --rm --no-deps app /app/scripts/protoc_gateway.sh $(REST_API_MODULES) diff --git a/api/swagger/superplane.swagger.json b/api/swagger/superplane.swagger.json index c1587f9d5b..688ffb3461 100644 --- a/api/swagger/superplane.swagger.json +++ b/api/swagger/superplane.swagger.json @@ -48,6 +48,9 @@ }, { "name": "ServiceAccounts" + }, + { + "name": "Scripts" } ], "schemes": [ @@ -2412,6 +2415,202 @@ ] } }, + "/api/v1/scripts": { + "get": { + "summary": "List scripts", + "description": "Returns a list of all scripts in the organization", + "operationId": "Scripts_ListScripts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ScriptsListScriptsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Script" + ] + }, + "post": { + "summary": "Create script", + "description": "Creates a new in-app script", + "operationId": "Scripts_CreateScript", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ScriptsCreateScriptResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ScriptsCreateScriptRequest" + } + } + ], + "tags": [ + "Script" + ] + } + }, + "/api/v1/scripts/{id}": { + "get": { + "summary": "Describe script", + "description": "Returns a script", + "operationId": "Scripts_DescribeScript", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ScriptsDescribeScriptResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Script" + ] + }, + "delete": { + "summary": "Delete script", + "description": "Deletes an existing script", + "operationId": "Scripts_DeleteScript", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ScriptsDeleteScriptResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Script" + ] + }, + "patch": { + "summary": "Update script", + "description": "Updates an existing script", + "operationId": "Scripts_UpdateScript", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ScriptsUpdateScriptResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ScriptsUpdateScriptBody" + } + } + ], + "tags": [ + "Script" + ] + } + }, + "/api/v1/scripts/{scriptId}/generate": { + "post": { + "summary": "Generate script", + "description": "Uses AI to generate or update script code based on a user prompt", + "operationId": "Scripts_GenerateScript", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ScriptsGenerateScriptResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "scriptId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ScriptsGenerateScriptBody" + } + } + ], + "tags": [ + "Script" + ] + } + }, "/api/v1/secrets": { "get": { "summary": "List secrets", @@ -3920,6 +4119,9 @@ }, "exampleOutput": { "type": "object" + }, + "source": { + "type": "string" } } }, @@ -5179,6 +5381,120 @@ } } }, + "ScriptsCreateScriptRequest": { + "type": "object", + "properties": { + "script": { + "$ref": "#/definitions/ScriptsScript" + } + } + }, + "ScriptsCreateScriptResponse": { + "type": "object", + "properties": { + "script": { + "$ref": "#/definitions/ScriptsScript" + } + } + }, + "ScriptsDeleteScriptResponse": { + "type": "object" + }, + "ScriptsDescribeScriptResponse": { + "type": "object", + "properties": { + "script": { + "$ref": "#/definitions/ScriptsScript" + } + } + }, + "ScriptsGenerateScriptBody": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "ScriptsGenerateScriptResponse": { + "type": "object", + "properties": { + "response": { + "type": "string" + }, + "source": { + "type": "string" + } + } + }, + "ScriptsListScriptsResponse": { + "type": "object", + "properties": { + "scripts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/ScriptsScript" + } + } + } + }, + "ScriptsScript": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "source": { + "type": "string" + }, + "manifestJson": { + "type": "string" + }, + "status": { + "type": "string" + }, + "createdBy": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "ScriptsUpdateScriptBody": { + "type": "object", + "properties": { + "script": { + "$ref": "#/definitions/ScriptsScript" + } + } + }, + "ScriptsUpdateScriptResponse": { + "type": "object", + "properties": { + "script": { + "$ref": "#/definitions/ScriptsScript" + } + } + }, "SecretLocal": { "type": "object", "properties": { @@ -5626,6 +5942,9 @@ }, "exampleData": { "type": "object" + }, + "source": { + "type": "string" } } }, diff --git a/db/migrations/20260222183740_add-scripts-table.down.sql b/db/migrations/20260222183740_add-scripts-table.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/db/migrations/20260222183740_add-scripts-table.up.sql b/db/migrations/20260222183740_add-scripts-table.up.sql new file mode 100644 index 0000000000..b8a2ab5229 --- /dev/null +++ b/db/migrations/20260222183740_add-scripts-table.up.sql @@ -0,0 +1,22 @@ +begin; + +CREATE TABLE scripts ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + organization_id uuid NOT NULL, + name CHARACTER VARYING(128) NOT NULL, + label CHARACTER VARYING(256) NOT NULL DEFAULT '', + description TEXT NOT NULL DEFAULT '', + source TEXT NOT NULL DEFAULT '', + manifest JSONB NOT NULL DEFAULT '{}'::jsonb, + status CHARACTER VARYING(32) NOT NULL DEFAULT 'draft', + created_by uuid REFERENCES users(id), + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + + PRIMARY KEY (id), + UNIQUE (organization_id, name) +); + +CREATE INDEX idx_scripts_organization_id ON scripts(organization_id); + +commit; diff --git a/db/structure.sql b/db/structure.sql index 5874db3992..f51a2c4a6d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -336,6 +336,25 @@ CREATE TABLE public.schema_migrations ( ); +-- +-- Name: scripts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.scripts ( + id uuid DEFAULT public.uuid_generate_v4() NOT NULL, + organization_id uuid NOT NULL, + name character varying(128) NOT NULL, + label character varying(256) DEFAULT ''::character varying NOT NULL, + description text DEFAULT ''::text NOT NULL, + source text DEFAULT ''::text NOT NULL, + manifest jsonb DEFAULT '{}'::jsonb NOT NULL, + status character varying(32) DEFAULT 'draft'::character varying NOT NULL, + created_by uuid, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + -- -- Name: secrets; Type: TABLE; Schema: public; Owner: - -- @@ -755,6 +774,22 @@ ALTER TABLE ONLY public.schema_migrations ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); +-- +-- Name: scripts scripts_organization_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scripts + ADD CONSTRAINT scripts_organization_id_name_key UNIQUE (organization_id, name); + + +-- +-- Name: scripts scripts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scripts + ADD CONSTRAINT scripts_pkey PRIMARY KEY (id); + + -- -- Name: secrets secrets_domain_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -1021,6 +1056,13 @@ CREATE INDEX idx_organizations_deleted_at ON public.organizations USING btree (d CREATE INDEX idx_role_metadata_lookup ON public.role_metadata USING btree (role_name, domain_type, domain_id); +-- +-- Name: idx_scripts_organization_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_scripts_organization_id ON public.scripts USING btree (organization_id); + + -- -- Name: idx_webhooks_app_installation_id; Type: INDEX; Schema: public; Owner: - -- @@ -1340,6 +1382,14 @@ ALTER TABLE ONLY public.organization_invite_links ADD CONSTRAINT organization_invite_links_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id) ON DELETE CASCADE; +-- +-- Name: scripts scripts_created_by_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scripts + ADD CONSTRAINT scripts_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.users(id); + + -- -- Name: users users_account_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -1532,7 +1582,7 @@ SET row_security = off; -- COPY public.schema_migrations (version, dirty) FROM stdin; -20260216151135 f +20260222183740 f \. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index cc82b7e62e..82ebd660bf 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -78,6 +78,9 @@ services: OTEL_SERVICE_NAME: "superplane-dev" OWNER_SETUP_ENABLED: "yes" VITE_ENABLE_CUSTOM_COMPONENTS: "true" + SUPERPLANE_PLUGINS_DIR: "/app/plugins" + SUPERPLANE_PLUGIN_HOST_PATH: "/app/plugin-host/dist/index.js" + OPENAI_API_KEY: "${OPENAI_API_KEY:-}" ports: - ${VITE_DEV_PORT:-5173}:${VITE_DEV_PORT:-5173} diff --git a/docs/prd/plugin-system.md b/docs/prd/plugin-system.md new file mode 100644 index 0000000000..69166f7ffb --- /dev/null +++ b/docs/prd/plugin-system.md @@ -0,0 +1,1555 @@ +# Plugin System + +## Overview + +SuperPlane plugins are extensions that add custom components, triggers, and integrations to the +platform. There are two ways to create plugins: + +- **Installed plugins** — developed as TypeScript projects, packaged into distributable archive + files (`.spx`), and installed via a CLI command. These are global to the SuperPlane instance + and suited for complex, production-grade integrations. +- **In-app scripts** — created directly in the SuperPlane UI through an AI-assisted builder. + These are scoped to a single organization, stored in the database, and suited for quick + custom components without any external tooling. + +Both paths use the same `@superplane/sdk` API and run in the same isolated Plugin Host process. + +Today, extending SuperPlane requires writing Go code in the main repository and redeploying the +entire application. This limits contributions to developers who know Go and have access to the +codebase. The plugin system removes that barrier entirely — for developers with the CLI +workflow, and for non-developers with the in-app builder. + +**Installed plugin lifecycle:** + +1. **Develop** — write TypeScript against the `@superplane/sdk` API. +2. **Package** — run `npx @superplane/cli plugin pack` to produce a `.spx` archive. +3. **Install** — run `superplane plugin install my-plugin-1.0.0.spx`. +4. **Run** — the server discovers installed plugins on startup, reads their manifests, and + activates them lazily. + +**In-app script lifecycle:** + +1. **Create** — open the Script Builder in the SuperPlane UI. +2. **Describe** — tell the AI assistant what the component should do. +3. **Refine** — review the generated code, iterate with the AI, edit manually if needed. +4. **Save** — the server validates the code, registers contributions, and activates it. + +All plugins run in a separate Node.js process — the Plugin Host — which communicates with the +Go backend over a local JSON-RPC channel. This process-level isolation means a crashing plugin +cannot bring down the server, and the Node.js runtime gives plugin authors access to the full +npm ecosystem. + +## Goals + +1. Allow operators and community contributors to extend SuperPlane with custom components, + triggers, and integrations — without touching Go code or recompiling the binary. +2. Provide a TypeScript-first development experience with a well-defined, versioned API. +3. Run plugins in an isolated Node.js process so that a faulty plugin cannot crash or degrade + the main server. +4. Support lazy activation: plugins load only when their contributions are actually needed. +5. Use declarative manifests (`package.json`) so the server knows what a plugin provides + without executing any of its code. +6. Register plugin-provided components, triggers, and integrations in the existing registry so + they are indistinguishable from built-in ones in the canvas and API. +7. Allow users to create simple plugins directly in the UI without setting up a development + environment, using an AI-assisted builder. + +## Non-Goals + +- **Marketplace / remote registry**: Plugins are packaged as `.spx` files and installed via the + CLI. A hosted package registry, in-app store, or auto-update mechanism is out of scope. +- **Hot-reloading during execution**: Installing a new version of a plugin restarts its + activation, but in-flight executions complete on the old code. There is no mid-execution + code swap. +- **Browser-side plugin code**: Plugins contribute backend logic only. Frontend rendering uses + the same generic mappers that built-in components use. The in-app builder generates server- + side TypeScript, not browser-side code. +- **Multi-language plugins**: The Plugin Host runs Node.js. Go, Python, or other runtimes are + not supported as plugin languages. +- **Sandboxed network access**: Plugins can make arbitrary HTTP calls from Node.js. Network + policy enforcement (allowlists, egress controls) is deferred to a later phase. +- **Full IDE experience**: The in-app builder is for quick prototyping of simple components. + Complex plugins with multi-file projects, integration lifecycle handlers, or advanced GitHub + App flows should use the `.spx` packaging workflow. + +## Architecture + +The plugin system is built on five core principles: + +1. **Manifest-driven contributions.** A plugin's `package.json` contains a `superplane.contributes` + section that declaratively lists everything the plugin provides — components, triggers, + integrations, their configuration schemas, output channels, and display metadata. The Go + server reads this JSON to populate the registry and render the canvas UI without ever + executing the plugin's code. + +2. **Packaged distribution.** Plugins are compiled, bundled, and packaged into `.spx` archives + before installation. The server never touches source files, `node_modules`, or build + tooling. It loads only the pre-built `extension.js` bundle from the installed archive. + +3. **Lazy activation.** Plugins declare `activationEvents` — conditions under which they should + be loaded. A plugin that contributes a data transformation component activates only when a + canvas node actually uses that component, not at startup. This keeps startup fast and memory + usage low. + +4. **Process isolation.** All plugins run in a dedicated child process (the Plugin Host), + separate from the main Go server. Communication happens over a structured JSON-RPC protocol. + If a plugin crashes, the Plugin Host catches the error and reports a failure — it does not + bring down the server. + +5. **Versioned API.** Plugins `import * as superplane from '@superplane/sdk'` to access + platform capabilities. The API surface is explicitly versioned — plugins declare which + SuperPlane version they require via `engines.superplane` in their manifest. + +### Process Architecture + +``` + ┌───────────────┐ + │ plugins.json │ (installed .spx plugins) + │ + manifests │ + └───────┬───────┘ + │ +┌─────────────────────────▼───────────────┐ +│ Go Server (main) │ +│ │ +│ ┌──────────┐ ┌──────────────────────┐ │ +│ │ Registry │ │ Plugin Manager │ │ +│ │ │◄─┤ │ │ +│ │Components│ │ - Reads installed │ │ JSON-RPC over stdio +│ │Triggers │ │ plugin manifests │─┼──────────────────────────┐ +│ │Integr. │ │ - Reads scripts DB │ │ │ +│ └──────────┘ │ - Manages lifecycle │ │ │ +│ └──────────────────────┘ │ │ +│ ▲ │ │ +└──────────────────────────┼──────────────┘ │ + │ │ + ┌────────┴────────┐ ┌────────────────▼──────────────────┐ + │ Scripts DB │ │ Plugin Host (Node.js) │ + │ (org-scoped │ │ │ + │ in-app │ │ ┌──────────────────────────────┐ │ + │ plugins) │ │ │ Plugin Loader │ │ + └─────────────────┘ │ │ - Requires each plugin │ │ + │ │ - Evaluates inline scripts │ │ + │ │ - Calls activate() │ │ + │ │ - Routes RPC to handlers │ │ + │ └──────────────────────────────┘ │ + │ │ + │ ┌────────┐ ┌────────┐ ┌────────┐ │ + │ │Plugin A│ │Plugin B│ │Script X│ │ + │ └────────┘ └────────┘ └────────┘ │ + │ │ + └────────────────────────────────────┘ +``` + +The Go server spawns one Plugin Host process. The Plugin Host loads all activated plugins in the +same Node.js runtime — both installed `.spx` plugins (loaded via `require()`) and in-app +scripts (loaded via inline activation). If a plugin throws an unhandled exception, the Plugin +Host catches it and +reports a failure for that execution — it does not crash the process. If the Plugin Host process +dies unexpectedly, the Plugin Manager on the Go side detects the broken pipe, restarts the +process, and re-activates all plugins. + +## Plugin Archive Format (`.spx`) + +A `.spx` file (SuperPlane Extension) is a zip archive containing the compiled, ready-to-run +plugin. It contains no source code, no `node_modules`, and no build tooling. The packaging step +bundles everything into a single JavaScript file. + +### Archive Contents + +``` +superplane-plugin-transform-1.0.0.spx (zip archive) +├── package.json ← manifest (contributes, activationEvents, engines) +├── extension.js ← single bundled entry point (all dependencies inlined) +├── README.md ← optional +└── icon.png ← optional plugin icon +``` + +The key properties: + +- **`package.json`** — the manifest. The `main` field always points to `extension.js`. +- **`extension.js`** — the entire plugin compiled and bundled into one file. The packaging + tool uses a bundler (esbuild) to resolve all npm dependencies and produce a single + self-contained output. No `node_modules` directory exists in the archive. +- **No source files** — TypeScript source, `tsconfig.json`, `src/`, test files, and dev + dependencies are excluded. The archive is a distribution artifact, not a development project. + +### Naming Convention + +Archive files follow the pattern `-.spx`: + +- `superplane-plugin-transform-1.0.0.spx` +- `superplane-plugin-pagerduty-custom-2.3.1.spx` + +### Development Project Structure + +During development, the plugin is a standard TypeScript project. The `.spx` archive is produced +from it by the packaging CLI: + +``` +superplane-plugin-transform/ ← development project (not shipped) +├── package.json +├── tsconfig.json +├── node_modules/ +├── src/ +│ └── index.ts +└── dist/ ← build output (intermediate, not shipped directly) + └── index.js +``` + +The developer runs `npm run build` (or `tsc`) during development, then +`npx @superplane/cli plugin pack` to produce the `.spx` archive for distribution. + +## Plugin Manifest (`package.json`) + +The manifest is the single source of truth for what a plugin provides. The Go server reads +manifests at startup without running any JavaScript. This is the declarative core of the system. + +```json +{ + "name": "superplane-plugin-transform", + "version": "1.0.0", + "description": "Data transformation components for SuperPlane", + "main": "dist/index.js", + "engines": { + "superplane": "^1.0.0" + }, + "superplane": { + "activationEvents": [ + "onComponent:transform.filter", + "onComponent:transform.reshape" + ], + "contributes": { + "components": [ + { + "name": "transform.filter", + "label": "Filter Data", + "description": "Filter incoming event data by field values", + "icon": "filter", + "color": "blue", + "configuration": [ + { + "name": "field", + "label": "Field", + "type": "string", + "required": true, + "description": "The field to filter on" + }, + { + "name": "value", + "label": "Value", + "type": "string", + "required": true, + "description": "The value to match" + } + ], + "outputChannels": [ + { "name": "matched", "label": "Matched" }, + { "name": "unmatched", "label": "Unmatched" } + ] + }, + { + "name": "transform.reshape", + "label": "Reshape Data", + "description": "Transform the structure of incoming data", + "icon": "shuffle", + "color": "purple", + "configuration": [ + { + "name": "mapping", + "label": "Field Mapping", + "type": "code", + "required": true, + "description": "JavaScript expression for the mapping" + } + ], + "outputChannels": [ + { "name": "default", "label": "Default" } + ] + } + ], + "triggers": [], + "integrations": [] + } + } +} +``` + +### Manifest Fields + +| Field | Required | Description | +|-----------------------------------|----------|---------------------------------------------------------------| +| `name` | Yes | npm package name. Convention: `superplane-plugin-`. | +| `version` | Yes | Semver version. | +| `main` | Yes | Entry point (compiled JS). | +| `engines.superplane` | Yes | Compatible SuperPlane version range. | +| `superplane.activationEvents` | Yes | When to activate the plugin (see Activation Events below). | +| `superplane.contributes` | Yes | Declarative list of components, triggers, and integrations. | + +### Activation Events + +Activation events control when a plugin's `activate()` function is called. Until activation, +the Plugin Host does not `require()` the plugin's code at all — it exists only as parsed +manifest data. + +| Event Pattern | Fires When | +|-----------------------------------|---------------------------------------------------------------| +| `onComponent:` | A canvas node using this component is set up or executed. | +| `onTrigger:` | A canvas node using this trigger is set up or fires. | +| `onIntegration:` | An integration of this type is configured or synced. | +| `*` | Immediately at Plugin Host startup. | + +A plugin with `"activationEvents": ["*"]` loads at startup. This is appropriate for plugins +that need to perform initialization (e.g., register webhook handlers) regardless of whether +their components are currently in use. + +A plugin with `"activationEvents": ["onComponent:transform.filter"]` loads only when a canvas +node references `transform.filter`. If no canvas on the instance uses that component, the +plugin never loads. + +### Contribution Points + +Each contribution type maps directly to a core interface: + +**Components** declare the same fields as `core.Component`: name, label, description, icon, +color, configuration fields, and output channels. The Go server reads these from the manifest +and creates placeholder entries in the registry. When a component is actually executed, the +Plugin Manager delegates to the Plugin Host. + +**Triggers** declare name, label, description, icon, color, configuration fields, and example +data — matching `core.Trigger`. + +**Integrations** declare name, label, description, icon, instructions, configuration fields, +and the list of component/trigger names they expose — matching `core.Integration`. + +## Plugin API (`@superplane/sdk`) + +Plugins import `@superplane/sdk` to interact with SuperPlane. This module is provided by the +Plugin Host runtime and is not an npm dependency that plugins install themselves — it is +available globally in the Plugin Host process at runtime. + +### Entry Point + +```typescript +import * as superplane from '@superplane/sdk'; + +export function activate(context: superplane.PluginContext) { + // Register component handlers + context.components.register('transform.filter', { + setup(ctx) { + if (!ctx.configuration.field) { + throw new Error('field is required'); + } + }, + + execute(ctx) { + const items = ctx.input.items || []; + const field = ctx.configuration.field; + const value = ctx.configuration.value; + + const matched = items.filter((item: any) => item[field] === value); + const unmatched = items.filter((item: any) => item[field] !== value); + + if (matched.length > 0) { + ctx.emit('matched', 'filtered', { items: matched, total: matched.length }); + } + + if (unmatched.length > 0) { + ctx.emit('unmatched', 'filtered', { items: unmatched, total: unmatched.length }); + } + + if (matched.length === 0 && unmatched.length === 0) { + ctx.pass(); + } + } + }); + + context.components.register('transform.reshape', { + execute(ctx) { + const mapping = new Function('data', ctx.configuration.mapping); + const result = mapping(ctx.input); + ctx.emit('default', 'reshaped', result); + } + }); +} + +export function deactivate() { + // Clean up resources if needed +} +``` + +### API Surface + +#### `superplane.PluginContext` + +Passed to `activate()`. This is the plugin's handle to the SuperPlane platform. + +```typescript +interface PluginContext { + /** Register handlers for components declared in the manifest. */ + components: ComponentRegistry; + + /** Register handlers for triggers declared in the manifest. */ + triggers: TriggerRegistry; + + /** Register handlers for integrations declared in the manifest. */ + integrations: IntegrationRegistry; + + /** Track disposable resources for cleanup on deactivate. */ + subscriptions: Disposable[]; + + /** Plugin-scoped logger. */ + log: Logger; +} +``` + +#### `ComponentRegistry` + +```typescript +interface ComponentRegistry { + register(name: string, handler: ComponentHandler): Disposable; +} + +interface ComponentHandler { + setup?(ctx: SetupContext): void | Promise; + execute(ctx: ExecutionContext): void | Promise; + cancel?(ctx: ExecutionContext): void | Promise; + cleanup?(ctx: SetupContext): void | Promise; + processQueueItem?(ctx: QueueItemContext): string | null | Promise; + handleAction?(ctx: ActionContext): void | Promise; + handleWebhook?(ctx: WebhookContext): WebhookResponse | Promise; +} +``` + +#### `TriggerRegistry` + +```typescript +interface TriggerRegistry { + register(name: string, handler: TriggerHandler): Disposable; +} + +interface TriggerHandler { + setup?(ctx: TriggerSetupContext): void | Promise; + cleanup?(ctx: TriggerSetupContext): void | Promise; + handleWebhook?(ctx: WebhookContext): WebhookResponse | Promise; + handleAction?(ctx: TriggerActionContext): Record | Promise>; +} +``` + +#### `IntegrationRegistry` + +```typescript +interface IntegrationRegistry { + register(name: string, handler: IntegrationHandler): Disposable; +} + +interface IntegrationHandler { + sync?(ctx: SyncContext): void | Promise; + cleanup?(ctx: IntegrationCleanupContext): void | Promise; + handleAction?(ctx: IntegrationActionContext): void | Promise; + handleWebhook?(setup: WebhookSetupContext): WebhookSetupResult | Promise; + listResources?(type: string, ctx: ListResourcesContext): IntegrationResource[] | Promise; + handleRequest?(ctx: HTTPRequestContext): void | Promise; +} +``` + +#### Execution Context + +The execution context mirrors the Go `core.ExecutionContext` — same capabilities, TypeScript +types: + +```typescript +interface ExecutionContext { + /** Unique execution ID. */ + id: string; + + /** Workflow that owns this execution. */ + workflowId: string; + + /** Organization that owns this workflow. */ + organizationId: string; + + /** Node that is executing. */ + nodeId: string; + + /** The upstream node that produced the input. */ + sourceNodeId: string; + + /** The base URL of the SuperPlane instance. */ + baseUrl: string; + + /** Input data from the upstream node or trigger. */ + input: any; + + /** Configuration values set by the user in the canvas. */ + configuration: Record; + + /** Evaluate a SuperPlane expression. */ + eval(expression: string): Promise>; + + /** Emit a payload to a named output channel. */ + emit(channel: string, payloadType: string, data: any | any[]): void; + + /** Pass the execution without emitting data. */ + pass(): void; + + /** Fail the execution with a reason and message. */ + fail(reason: string, message: string): void; + + /** Set a key-value pair on the execution state. */ + setKV(key: string, value: string): void; + + /** Execution-scoped metadata (persisted across retries). */ + metadata: MetadataAccessor; + + /** Node-scoped metadata (persisted across executions). */ + nodeMetadata: MetadataAccessor; + + /** Make HTTP requests through SuperPlane's managed HTTP client. */ + http: HTTPClient; + + /** Read secrets from the organization's secret store. */ + secrets: SecretsAccessor; + + /** Access integration context when running under an integration. */ + integration: IntegrationAccessor; + + /** Logger scoped to this execution. */ + log: Logger; +} + +interface MetadataAccessor { + get(): Promise; + set(value: any): Promise; +} + +interface HTTPClient { + request(method: string, url: string, options?: HTTPOptions): Promise; +} + +interface HTTPOptions { + headers?: Record; + body?: string; + timeout?: number; +} + +interface HTTPResponse { + status: number; + headers: Record; + body: any; +} + +interface SecretsAccessor { + getKey(secretName: string, keyName: string): Promise; +} + +interface Logger { + info(message: string, ...args: any[]): void; + warn(message: string, ...args: any[]): void; + error(message: string, ...args: any[]): void; + debug(message: string, ...args: any[]): void; +} + +interface Disposable { + dispose(): void; +} +``` + +### Async Support + +All handler methods can return `void` or `Promise`. The Plugin Host awaits promises and +translates the resolved/rejected state back to the Go server. This means plugins can use +`async/await` naturally: + +```typescript +async execute(ctx: ExecutionContext) { + const token = await ctx.secrets.getKey('api-credentials', 'token'); + + const response = await ctx.http.request('GET', 'https://api.example.com/data', { + headers: { 'Authorization': `Bearer ${token}` }, + timeout: 5000, + }); + + if (response.status !== 200) { + ctx.fail('api_error', `API returned ${response.status}`); + return; + } + + ctx.emit('default', 'api_response', response.body); +} +``` + +## Packaging CLI + +The `@superplane/cli` package provides a `plugin pack` command that builds a `.spx` archive +from a TypeScript plugin project. + +### Usage + +```bash +# From within the plugin project directory: +npx @superplane/cli plugin pack + +# Output: +# ✓ Compiled TypeScript → dist/index.js +# ✓ Bundled with esbuild → extension.js (148 KB) +# ✓ Validated package.json manifest +# ✓ Created superplane-plugin-transform-1.0.0.spx +``` + +### What `plugin pack` Does + +1. **Compile** — runs `tsc` (or uses the project's build script) to produce JavaScript from + TypeScript source. +2. **Bundle** — runs esbuild to bundle the compiled entry point and all its npm dependencies + into a single `extension.js` file. The `@superplane/sdk` import is marked as external + (it's provided by the Plugin Host at runtime, not bundled). +3. **Validate** — checks that `package.json` contains a valid `superplane` field with + `contributes` and `activationEvents`. Checks that `engines.superplane` is set. Checks that + the bundled entry point exports `activate`. +4. **Package** — creates a zip archive with the `.spx` extension containing `package.json`, + `extension.js`, and any declared static assets (README, icon). + +### Validation Errors + +The CLI rejects packaging if: + +- `package.json` is missing or lacks the `superplane` field. +- `engines.superplane` is not set. +- The entry point doesn't export an `activate` function. +- Contributed names are empty or contain invalid characters. +- Configuration fields reference unsupported types. + +## Plugin Installation + +### Install Command + +```bash +# Install from a local .spx file: +superplane plugin install superplane-plugin-transform-1.0.0.spx + +# Install from a URL: +superplane plugin install https://releases.example.com/superplane-plugin-transform-1.0.0.spx + +# List installed plugins: +superplane plugin list + +# Uninstall: +superplane plugin uninstall superplane-plugin-transform + +# Show details: +superplane plugin info superplane-plugin-transform +``` + +### What `plugin install` Does + +1. **Extract** — unzips the `.spx` archive into a subdirectory under the managed plugins + directory: `//`. +2. **Validate** — reads the extracted `package.json`, checks `engines.superplane` compatibility, + checks for name collisions with built-in or other installed plugins. +3. **Register** — writes a record of the installed plugin (name, version, install time) to a + `plugins.json` manifest file in the plugins directory. +4. **Signal** — if the server is running, sends a `SIGHUP` to trigger a plugin reload. The + server re-scans the plugins directory, picks up the new plugin, registers its contributions, + and activates it if needed. + +### Version Management + +Installing a plugin that is already installed replaces it: + +```bash +# Upgrade: install the new version over the old one +superplane plugin install superplane-plugin-transform-2.0.0.spx +# → Replaces 1.0.0, deactivates old plugin, activates new one +``` + +Only one version of a plugin can be installed at a time. The install command extracts the new +archive, deactivates the old version (if the server is running), and activates the new one. + +### Managed Directory Layout + +The plugins directory is fully managed by the CLI and the server. Operators do not manually +create or modify files in it. + +``` +plugins/ ← SUPERPLANE_PLUGINS_DIR +├── plugins.json ← registry of installed plugins +├── superplane-plugin-transform/ +│ ├── package.json +│ └── extension.js +├── superplane-plugin-slack-utils/ +│ ├── package.json +│ └── extension.js +└── superplane-plugin-custom-approval/ + ├── package.json + └── extension.js +``` + +The `plugins.json` file tracks what is installed: + +```json +{ + "plugins": [ + { + "name": "superplane-plugin-transform", + "version": "1.0.0", + "installedAt": "2026-02-20T10:30:00Z" + }, + { + "name": "superplane-plugin-slack-utils", + "version": "0.5.2", + "installedAt": "2026-02-19T14:00:00Z" + } + ] +} +``` + +## Plugin Discovery and Loading + +### Startup Sequence + +1. **Read installed plugins.** The Plugin Manager reads `SUPERPLANE_PLUGINS_DIR/plugins.json`. + For each entry, it reads the `package.json` from the corresponding subdirectory. + +2. **Validate manifests.** For each installed plugin: + - Check `engines.superplane` compatibility with the running server version. + - Validate that all contributed names are unique across all plugins (and don't collide with + built-in names). + - Validate that `extension.js` exists. + - If validation fails, log an error and skip the plugin. + +3. **Register contributions.** For each valid plugin, create adapter entries in the Go registry: + - `PluginComponentAdapter` implements `core.Component`. Its metadata methods (Name, Label, + Configuration, OutputChannels, etc.) return data from the manifest. Its execution methods + (Setup, Execute, etc.) delegate to the Plugin Host over JSON-RPC. + - `PluginTriggerAdapter` implements `core.Trigger`, same pattern. + - `PluginIntegrationAdapter` implements `core.Integration`, same pattern. + +4. **Spawn Plugin Host.** Start the Node.js child process. The Plugin Host receives the list of + installed plugin paths and their activation events. + +5. **Activate eager plugins.** Plugins with `"activationEvents": ["*"]` are activated + immediately — the Plugin Host calls `require()` on their `extension.js` and invokes + `activate()`. + +### Lazy Activation Flow + +When a component from a not-yet-activated plugin is first needed: + +``` +Canvas node references "transform.filter" + → Node executor calls registry.GetComponent("transform.filter") + → Returns PluginComponentAdapter + → Adapter calls PluginManager.EnsureActivated("superplane-plugin-transform") + → Plugin Manager sends "activate" RPC to Plugin Host + → Plugin Host calls require("/superplane-plugin-transform/extension.js") + → activate(context) is called + → Plugin registers its handlers + → Adapter sends "execute" RPC to Plugin Host + → Plugin Host routes to the registered handler + → Result returned to Go server +``` + +Subsequent calls to the same plugin skip activation — it's already loaded. + +### Live Install / Uninstall + +When a plugin is installed or uninstalled while the server is running (via `superplane plugin +install` / `uninstall`), the CLI sends `SIGHUP` to the server process. The server: + +1. Re-reads `plugins.json`. +2. Compares the current set of installed plugins against what is loaded. +3. For new plugins: validates, registers contributions, and signals the Plugin Host to prepare + for activation. +4. For removed plugins: deactivates in the Plugin Host, unregisters from the Go registry. +5. For updated plugins (same name, new version): deactivates old, loads new manifest, registers + updated contributions, re-activates. + +In-flight executions on old plugin versions complete normally. + +## Communication Protocol + +The Go server and Plugin Host communicate over the child process's stdin/stdout using JSON-RPC +2.0. Each message is a single JSON object terminated by a newline. + +### Message Flow + +**Go → Plugin Host (requests):** + +```json +{"jsonrpc":"2.0","id":1,"method":"plugin/activate","params":{"pluginId":"superplane-plugin-transform"}} +{"jsonrpc":"2.0","id":2,"method":"component/execute","params":{"pluginId":"superplane-plugin-transform","component":"transform.filter","context":{...}}} +{"jsonrpc":"2.0","id":3,"method":"component/setup","params":{"pluginId":"superplane-plugin-transform","component":"transform.filter","context":{...}}} +{"jsonrpc":"2.0","id":4,"method":"trigger/handleWebhook","params":{"pluginId":"superplane-plugin-events","trigger":"events.github","context":{...}}} +``` + +**Plugin Host → Go (responses):** + +```json +{"jsonrpc":"2.0","id":2,"result":{"action":"emit","channel":"matched","payloadType":"filtered","data":{...}}} +{"jsonrpc":"2.0","id":2,"error":{"code":-32000,"message":"field is required"}} +``` + +**Plugin Host → Go (requests for context operations):** + +When plugin code calls `ctx.secrets.getKey()`, `ctx.http.request()`, `ctx.metadata.get()`, or +similar context methods, the Plugin Host sends a request to the Go server and blocks the handler +until the response arrives: + +```json +{"jsonrpc":"2.0","id":100,"method":"ctx/secrets.getKey","params":{"executionId":"...","secretName":"api-creds","keyName":"token"}} +{"jsonrpc":"2.0","id":101,"method":"ctx/http.request","params":{"executionId":"...","method":"GET","url":"https://api.example.com","options":{...}}} +``` + +The Go server fulfills these using the same `SecretsContext`, `HTTPContext`, etc. that built-in +components use — same authorization, same audit trail, same rate limits. + +### RPC Methods + +| Method | Direction | Description | +|-------------------------------|--------------------|------------------------------------------------| +| `plugin/activate` | Go → Plugin Host | Activate a plugin (require + call activate) | +| `plugin/deactivate` | Go → Plugin Host | Deactivate a plugin (call deactivate) | +| `component/setup` | Go → Plugin Host | Call a component's setup handler | +| `component/execute` | Go → Plugin Host | Call a component's execute handler | +| `component/cancel` | Go → Plugin Host | Call a component's cancel handler | +| `component/cleanup` | Go → Plugin Host | Call a component's cleanup handler | +| `component/handleAction` | Go → Plugin Host | Call a component's action handler | +| `component/handleWebhook` | Go → Plugin Host | Call a component's webhook handler | +| `component/processQueueItem` | Go → Plugin Host | Call a component's queue item processor | +| `trigger/setup` | Go → Plugin Host | Call a trigger's setup handler | +| `trigger/cleanup` | Go → Plugin Host | Call a trigger's cleanup handler | +| `trigger/handleWebhook` | Go → Plugin Host | Call a trigger's webhook handler | +| `trigger/handleAction` | Go → Plugin Host | Call a trigger's action handler | +| `integration/sync` | Go → Plugin Host | Call an integration's sync handler | +| `integration/cleanup` | Go → Plugin Host | Call an integration's cleanup handler | +| `integration/handleAction` | Go → Plugin Host | Call an integration's action handler | +| `integration/listResources` | Go → Plugin Host | Call an integration's resource lister | +| `ctx/secrets.getKey` | Plugin Host → Go | Read a secret key | +| `ctx/http.request` | Plugin Host → Go | Make an HTTP request through managed client | +| `ctx/metadata.get` | Plugin Host → Go | Read execution/node metadata | +| `ctx/metadata.set` | Plugin Host → Go | Write execution/node metadata | +| `ctx/eval` | Plugin Host → Go | Evaluate a SuperPlane expression | +| `ctx/integration.getConfig` | Plugin Host → Go | Read integration configuration | +| `ctx/integration.setMetadata` | Plugin Host → Go | Write integration metadata | +| `ctx/integration.subscribe` | Plugin Host → Go | Subscribe to integration events | +| `ctx/webhook.setup` | Plugin Host → Go | Set up a webhook endpoint | + +## Registry Integration + +Plugin-contributed items appear in the registry identically to built-in ones. The adapter +pattern makes this transparent: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Registry │ +│ │ +│ Components: │ +│ "filter" → built-in FilterComponent (Go) │ +│ "http" → built-in HTTPComponent (Go) │ +│ "transform.filter" → PluginComponentAdapter │ +│ "transform.reshape" → PluginComponentAdapter │ +│ │ +│ Triggers: │ +│ "webhook" → built-in WebhookTrigger (Go) │ +│ "events.github" → PluginTriggerAdapter │ +│ │ +│ Integrations: │ +│ "github" → built-in GitHubIntegration (Go) │ +│ "custom-service" → PluginIntegrationAdapter │ +└─────────────────────────────────────────────────────────────┘ +``` + +The `PluginComponentAdapter` implements every method of `core.Component`: + +- **Metadata methods** (`Name()`, `Label()`, `Configuration()`, `OutputChannels()`, etc.) + return data parsed from the manifest JSON. These never cross the process boundary. +- **Execution methods** (`Setup()`, `Execute()`, `Cancel()`, etc.) send an RPC to the Plugin + Host and wait for the response. If the plugin is not yet activated, the adapter triggers + activation first. + +This means: + +- The component listing API (`ListComponents`) works without any changes — it iterates the + registry and returns all entries. +- The canvas node editor renders plugin components using the same configuration schema format. +- The node executor calls `component.Execute(ctx)` and gets back a result — it has no idea + whether the component is Go or JavaScript. + +## Naming Conventions + +Plugin-contributed names use dot-separated prefixes derived from the plugin name: + +- Plugin `superplane-plugin-transform` contributes `transform.filter`, `transform.reshape`. +- Plugin `superplane-plugin-slack-utils` contributes `slack-utils.format-message`. + +In-app scripts use a `script.` prefix to separate them from installed plugins: + +- Script "My Filter" contributes `script.my-filter`. +- Script "Slack Notify" contributes `script.slack-notify`. + +This follows the existing convention where integration components use the integration name as a +prefix (e.g., `github.create-issue`, `slack.send-message`). + +The Plugin Manager validates at startup that no contributed name collides with a built-in name, +a name from another plugin, or a name from another script. + +## Resource Limits + +| Limit | Default | Environment Variable | +|------------------------------|------------|-----------------------------------------| +| Execution timeout | 30 seconds | `SUPERPLANE_PLUGIN_EXECUTION_TIMEOUT` | +| Plugin activation timeout | 10 seconds | `SUPERPLANE_PLUGIN_ACTIVATION_TIMEOUT` | +| HTTP requests per execution | 10 | `SUPERPLANE_PLUGIN_MAX_HTTP_REQUESTS` | +| HTTP request timeout | 10 seconds | `SUPERPLANE_PLUGIN_HTTP_TIMEOUT` | +| Plugin Host memory limit | 512 MB | `SUPERPLANE_PLUGIN_HOST_MEMORY_LIMIT` | +| Max plugins | 50 | `SUPERPLANE_PLUGIN_MAX_COUNT` | + +When a limit is exceeded: +- **Execution timeout**: The Go server cancels the pending RPC and fails the execution. +- **Activation timeout**: The plugin is marked as failed and its contributions are unavailable. +- **Plugin Host memory**: The Node.js process is killed and restarted via `--max-old-space-size`. + +## Error Handling + +### Plugin Crashes + +If a plugin throws an unhandled exception during `execute()`, the Plugin Host catches it and +returns an RPC error response. The Go server fails the execution with the error message. The +plugin remains loaded — a single execution failure does not unload the plugin. + +### Plugin Host Crashes + +If the Plugin Host process exits unexpectedly: + +1. The Plugin Manager detects the broken stdin/stdout pipe. +2. All pending RPC calls are failed with "Plugin Host unavailable." +3. The Plugin Manager waits 1 second and respawns the Plugin Host. +4. All previously activated plugins are re-activated. +5. If the Plugin Host crashes 5 times within 60 seconds, the Plugin Manager stops restarting + and logs a critical error. Plugin-based components/triggers return errors until an operator + intervenes. + +### Malformed Plugins + +- **Bad manifest**: Rejected at install time by the CLI. If a previously valid plugin becomes + incompatible after a server upgrade, it is logged and skipped at startup. +- **Missing `extension.js`**: Rejected at install time. If the file is somehow missing from an + installed plugin directory, activation fails and the plugin is marked as errored. +- **activate() throws**: Plugin marked as errored. Its contributions remain in the registry + but return errors when used. +- **Incompatible engine version**: Rejected at install time. Logged and skipped at startup if + the server version changes. + +## Configuration + +| Environment Variable | Default | Description | +|------------------------------------------|---------------|-----------------------------------------------------| +| `SUPERPLANE_PLUGINS_DIR` | `plugins` | Path to managed directory for installed plugins. | +| `SUPERPLANE_PLUGIN_HOST_MEMORY_LIMIT` | `512MB` | Max memory for the Plugin Host process. | +| `SUPERPLANE_PLUGIN_EXECUTION_TIMEOUT` | `30s` | Max execution time per handler call. | +| `SUPERPLANE_PLUGIN_ACTIVATION_TIMEOUT` | `10s` | Max time for a plugin to activate. | +| `SUPERPLANE_PLUGIN_MAX_HTTP_REQUESTS` | `10` | Max HTTP requests per execution. | +| `SUPERPLANE_PLUGIN_HTTP_TIMEOUT` | `10s` | Timeout for individual HTTP requests. | +| `SUPERPLANE_PLUGIN_MAX_COUNT` | `50` | Max number of plugins that can be installed. | +| `SUPERPLANE_PLUGIN_NODE_PATH` | (auto-detect) | Path to the Node.js binary. | +| `OPENAI_API_KEY` | (none) | API key for AI-assisted script generation. If unset, the AI chat feature in the Script Builder is disabled. | + +If `SUPERPLANE_PLUGINS_DIR` does not exist or contains no `plugins.json`, the installed plugin +system is disabled — no Plugin Host is spawned for installed plugins. However, the server still +loads in-app scripts from the database and starts the Plugin Host if any active scripts exist. + +## Canvas Integration + +Plugin components, triggers, and integrations appear in the canvas alongside built-in ones. + +- **Component picker**: Plugin components appear in a "Plugins" section, grouped by plugin + name. The icon and color from the manifest are used. +- **Configuration panel**: The sidebar renders configuration fields from the manifest using the + existing `configuration.Field` schema — same UI as built-in components. +- **Run history**: Execution states, subtitles, and details use the default mappers. Plugin + components don't need custom frontend mappers. +- **Integration panel**: Plugin integrations appear in the integrations list with their declared + configuration fields and instructions. + +Canvas nodes reference plugin components using the existing `Ref` structure: + +```json +{ + "component": { + "name": "transform.filter" + } +} +``` + +## Complete Plugin Example + +A full plugin that contributes a component and a trigger, showing the full lifecycle from +source to installation. This plugin creates GitHub issues and listens for new issues via +webhooks. + +### Source Project + +**`package.json`:** + +```json +{ + "name": "superplane-plugin-github-issues", + "version": "1.0.0", + "description": "Create and listen for GitHub issues", + "main": "dist/index.js", + "engines": { + "superplane": "^1.0.0" + }, + "superplane": { + "activationEvents": [ + "onComponent:github-issues.create-issue", + "onTrigger:github-issues.on-issue-created" + ], + "contributes": { + "components": [ + { + "name": "github-issues.create-issue", + "label": "Create GitHub Issue", + "description": "Open a new issue in a GitHub repository", + "icon": "github", + "color": "gray", + "configuration": [ + { "name": "owner", "label": "Repository Owner", "type": "string", "required": true }, + { "name": "repo", "label": "Repository Name", "type": "string", "required": true } + ], + "outputChannels": [ + { "name": "default", "label": "Default" } + ] + } + ], + "triggers": [ + { + "name": "github-issues.on-issue-created", + "label": "GitHub Issue Created", + "description": "Fires when a new issue is opened in a GitHub repository", + "icon": "github", + "color": "gray", + "configuration": [ + { "name": "owner", "label": "Repository Owner", "type": "string", "required": true }, + { "name": "repo", "label": "Repository Name", "type": "string", "required": true } + ], + "exampleData": { + "action": "opened", + "issue": { + "number": 42, + "title": "Bug: login page returns 500", + "body": "Steps to reproduce...", + "state": "open", + "html_url": "https://github.com/acme/app/issues/42", + "user": { "login": "octocat" }, + "labels": [{ "name": "bug" }], + "created_at": "2026-02-20T10:30:00Z" + }, + "repository": { + "full_name": "acme/app" + } + } + } + ], + "integrations": [] + } + } +} +``` + +**`src/index.ts`:** + +```typescript +import * as superplane from '@superplane/sdk'; +import * as crypto from 'crypto'; + +export function activate(context: superplane.PluginContext) { + context.components.register('github-issues.create-issue', { + async setup(ctx) { + const token = await ctx.secrets.getKey('github', 'token'); + if (!token) { + throw new Error('GitHub token not configured — add a "github" secret with a "token" key'); + } + }, + + async execute(ctx) { + const token = await ctx.secrets.getKey('github', 'token'); + const { owner, repo } = ctx.configuration; + + const response = await ctx.http.request( + 'POST', + `https://api.github.com/repos/${owner}/${repo}/issues`, + { + headers: { + 'Authorization': `Bearer ${token}`, + 'Accept': 'application/vnd.github+json', + 'Content-Type': 'application/json', + 'X-GitHub-Api-Version': '2022-11-28', + }, + body: JSON.stringify({ + title: ctx.input.title, + body: ctx.input.body || '', + labels: ctx.input.labels || [], + assignees: ctx.input.assignees || [], + }), + } + ); + + if (response.status !== 201) { + ctx.fail('api_error', `GitHub API returned ${response.status}: ${response.body?.message}`); + return; + } + + ctx.emit('default', 'issue_created', { + number: response.body.number, + title: response.body.title, + html_url: response.body.html_url, + state: response.body.state, + }); + } + }); + + context.triggers.register('github-issues.on-issue-created', { + async setup(ctx) { + const webhookUrl = await ctx.webhook.setup(); + const token = await ctx.secrets.getKey('github', 'token'); + const webhookSecret = await ctx.webhook.getSecret(); + const { owner, repo } = ctx.configuration; + + const metadata = await ctx.metadata.get(); + if (metadata?.webhookId) { + return; + } + + const response = await ctx.http.request( + 'POST', + `https://api.github.com/repos/${owner}/${repo}/hooks`, + { + headers: { + 'Authorization': `Bearer ${token}`, + 'Accept': 'application/vnd.github+json', + 'Content-Type': 'application/json', + 'X-GitHub-Api-Version': '2022-11-28', + }, + body: JSON.stringify({ + config: { + url: webhookUrl, + content_type: 'json', + secret: webhookSecret, + }, + events: ['issues'], + active: true, + }), + } + ); + + if (response.status !== 201) { + throw new Error(`Failed to create GitHub webhook: ${response.body?.message}`); + } + + await ctx.metadata.set({ webhookId: response.body.id }); + }, + + async cleanup(ctx) { + const metadata = await ctx.metadata.get(); + if (!metadata?.webhookId) { + return; + } + + const token = await ctx.secrets.getKey('github', 'token'); + const { owner, repo } = ctx.configuration; + + await ctx.http.request( + 'DELETE', + `https://api.github.com/repos/${owner}/${repo}/hooks/${metadata.webhookId}`, + { + headers: { + 'Authorization': `Bearer ${token}`, + 'Accept': 'application/vnd.github+json', + 'X-GitHub-Api-Version': '2022-11-28', + }, + } + ); + }, + + async handleWebhook(ctx) { + const signature = ctx.headers['x-hub-signature-256']; + const webhookSecret = await ctx.webhook.getSecret(); + + const expected = 'sha256=' + crypto + .createHmac('sha256', webhookSecret) + .update(ctx.body) + .digest('hex'); + + if (signature !== expected) { + return { status: 401 }; + } + + const payload = JSON.parse(ctx.body); + + if (payload.action !== 'opened') { + return { status: 200 }; + } + + ctx.events.emit('issue_created', payload); + return { status: 200 }; + } + }); +} + +export function deactivate() {} +``` + +### Package and Install + +```bash +# Build and package: +cd superplane-plugin-github-issues +npm install +npm run build +npx @superplane/cli plugin pack +# → superplane-plugin-github-issues-1.0.0.spx + +# Install on the server: +superplane plugin install superplane-plugin-github-issues-1.0.0.spx +# → Extracted to plugins/superplane-plugin-github-issues/ +# → Registered: github-issues.create-issue (component) +# → Registered: github-issues.on-issue-created (trigger) +# → Server signaled to reload plugins + +# Verify: +superplane plugin list +# NAME VERSION INSTALLED +# superplane-plugin-github-issues 1.0.0 2026-02-20T10:30:00Z +``` + +### What Gets Installed + +``` +plugins/superplane-plugin-github-issues/ +├── package.json ← manifest only (no devDependencies, no scripts) +└── extension.js ← single bundled file (all deps inlined) +``` + +No `node_modules/`, no `src/`, no `tsconfig.json`, no build artifacts beyond the single +`extension.js` bundle. + +## In-App Plugin Builder + +### Overview + +The Script Builder lets users create plugins directly in the SuperPlane UI without installing +any tooling, writing a `package.json`, or running CLI commands. Users describe what they need in +a chat interface, and an AI assistant generates TypeScript code against the `@superplane/sdk` +API. The generated code can be reviewed, edited, and saved — at which point it becomes a live +component or trigger available in the canvas. + +In-app scripts are organization-scoped. They appear in the component/trigger picker only for the +organization that created them, unlike installed `.spx` plugins which are available globally. + +### UI Layout + +The Script Builder page is accessible from the main navigation under "Scripts." The layout has +three panels: + +``` +┌──────────────────────────────────────────────────────────────────────────┐ +│ Scripts │ +├─────────────┬──────────────────────────────┬─────────────────────────────┤ +│ │ │ Script Name: [ My Filter ] │ +│ Script 1 │ AI Chat │ │ +│ Script 2 ● │ │ ┌─────────────────────────┐│ +│ Script 3 │ User: I need a component │ │ import * as sp from ││ +│ │ that filters events by │ │ "@superplane/sdk"; ││ +│ [+ New] │ severity... │ │ ││ +│ │ │ │ export function ││ +│ │ AI: Here's a component │ │ activate(ctx) { ││ +│ │ that filters... │ │ ctx.components ││ +│ │ │ │ .register(...) ││ +│ │ │ │ } ││ +│ │ [Send message...] │ │ ││ +│ │ │ └─────────────────────────┘│ +│ │ │ │ +│ │ │ Status: Active ● │ +│ │ │ [Save] [Delete] │ +├─────────────┴──────────────────────────────┴─────────────────────────────┤ +``` + +- **Left sidebar**: Lists all scripts in the current organization. Shows status indicator + (draft, active, error). "New" button creates a blank script. +- **Center panel**: AI chat assistant. Users describe what they want in natural language. The + assistant generates code and explains it. Each script has its own chat history. +- **Right panel**: Code editor with the script source. Includes the script name, a syntax- + highlighted editor with the TypeScript/JavaScript source code, status indicator, and + save/delete actions. + +### Database Model + +In-app scripts are stored in a `scripts` table: + +```sql +CREATE TABLE scripts ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + organization_id UUID NOT NULL REFERENCES organizations(id), + name TEXT NOT NULL, + label TEXT NOT NULL, + description TEXT NOT NULL DEFAULT '', + source TEXT NOT NULL DEFAULT '', + manifest JSONB NOT NULL DEFAULT '{}', + status TEXT NOT NULL DEFAULT 'draft', + created_by UUID REFERENCES users(id), + created_at TIMESTAMP NOT NULL DEFAULT NOW(), + updated_at TIMESTAMP NOT NULL DEFAULT NOW(), + + UNIQUE (organization_id, name) +); +``` + +- `source`: The TypeScript/JavaScript source code — a single-file plugin. +- `manifest`: The `superplane` manifest section extracted from the code on save. Contains + `contributes` (components, triggers) and `activationEvents`. This is auto-generated by + parsing the code's `activate()` function for registration calls, or declared explicitly in a + comment block. +- `status`: One of `draft` (not yet activated), `active` (running in Plugin Host), or `error` + (activation failed). + +### API + +A new gRPC service `Scripts` handles CRUD and AI generation: + +```protobuf +service Scripts { + rpc ListScripts(ListScriptsRequest) returns (ListScriptsResponse); + rpc DescribeScript(DescribeScriptRequest) returns (DescribeScriptResponse); + rpc CreateScript(CreateScriptRequest) returns (CreateScriptResponse); + rpc UpdateScript(UpdateScriptRequest) returns (UpdateScriptResponse); + rpc DeleteScript(DeleteScriptRequest) returns (DeleteScriptResponse); + rpc GenerateScript(GenerateScriptRequest) returns (GenerateScriptResponse); +} +``` + +- **ListScripts**: Returns all scripts for the current organization. +- **DescribeScript**: Returns a single script with full source and manifest. +- **CreateScript**: Creates a new script in `draft` status. +- **UpdateScript**: Updates source, name, or description. If the script is `active`, the + server re-validates, re-registers contributions, and re-activates in the Plugin Host. +- **DeleteScript**: Deactivates the script in the Plugin Host, unregisters contributions, + and deletes the database row. +- **GenerateScript**: Sends a user message to the AI backend and returns the assistant's + response (which includes generated code). Maintains chat history per script. + +The proto file follows the pattern of existing services like `blueprints.proto`. + +### Plugin Host Integration + +Installed plugins activate via `require(filePath)`. In-app scripts need a different mechanism +since their code lives in the database, not on the filesystem. + +A new RPC method `plugin/activateInline` is added to the Plugin Host: + +```json +{ + "method": "plugin/activateInline", + "params": { + "pluginId": "script.my-filter", + "source": "const sp = require('@superplane/sdk');\nexport function activate(ctx) { ... }", + "manifest": { "contributes": { "components": [...] } } + } +} +``` + +The Plugin Host evaluates the source code using Node.js `vm` module, then calls `activate()` +the same way it does for file-based plugins. From this point forward, the script's handlers +are routed identically to installed plugin handlers. + +When a script is updated (source changes), the server sends `plugin/deactivate` followed by +`plugin/activateInline` with the new source. + +### Registration Flow + +When a script is saved with source code: + +1. The server parses the source to extract the manifest (contributed components, triggers). +2. The manifest is stored in the `scripts.manifest` JSONB column. +3. Contributions are registered in the registry with the `script.` prefix. +4. The Plugin Host receives `plugin/activateInline` with the source. +5. The script status is set to `active`. + +If step 4 fails (e.g., syntax error, `activate()` throws), the status is set to `error` with +the error message, and contributions are unregistered. + +### AI-Assisted Code Generation + +The AI chat backend proxies messages to a configurable LLM provider (OpenAI by default). The +system prompt includes: + +- The `@superplane/sdk` API reference (component registration, trigger registration, context + interfaces, available methods). +- Examples of well-structured plugins. +- Constraints (single-file plugin, must export `activate()`, must use `@superplane/sdk`). + +The AI generates complete, runnable plugin code. Users can iterate by describing changes in +natural language. The chat history is maintained per script so the AI has context for follow-up +requests. + +### Coexistence with Installed Plugins + +In-app scripts and installed `.spx` plugins coexist in the same Plugin Host and registry: + +| Aspect | Installed Plugins (.spx) | In-App Scripts | +|---------------------|-------------------------------------|----------------------------------------| +| Storage | Filesystem (`plugins/` directory) | Database (`scripts` table) | +| Scope | Global (all organizations) | Organization-scoped | +| Naming prefix | Plugin name (e.g., `github-issues`) | `script.` (e.g., `script.my-filter`) | +| Authoring | External IDE + CLI | In-app UI + AI assistant | +| Activation | `require()` file path | `plugin/activateInline` with source | +| Lifecycle | CLI install/uninstall + SIGHUP | API create/update/delete | +| Manifest source | `package.json` file | Extracted from code, stored in DB | + +Name collisions between the two namespaces are not possible because of the `script.` prefix. +Within the script namespace, names are unique per organization. + +## Implementation Plan + +### Phase 1: Packaging CLI and Archive Format + +1. Define the `.spx` archive format (zip structure, required files). +2. Implement `plugin pack` in `@superplane/cli` — compile, bundle with esbuild (marking + `@superplane/sdk` as external), validate manifest, produce `.spx` archive. +3. Implement `plugin install` / `plugin uninstall` / `plugin list` commands — extract archive, + manage `plugins.json`, signal server via `SIGHUP`. +4. Implement manifest validation (engine compatibility, name format, configuration schema). + +At the end of Phase 1, plugins can be packaged and installed on disk, but the server doesn't +load them yet. + +### Phase 2: Plugin Manager and Registry Adapters + +1. Implement `pkg/plugins/manifest.go` — parse `package.json` from installed plugin + directories, extract contribution definitions. +2. Implement `pkg/plugins/manager.go` — read `plugins.json`, load manifests, manage plugin + lifecycle state, handle `SIGHUP` for live reload. +3. Implement `pkg/plugins/adapters.go` — `PluginComponentAdapter`, `PluginTriggerAdapter`, + `PluginIntegrationAdapter` that implement the core interfaces using manifest data for + metadata and RPC for execution. +4. Wire manifest-based registration into `cmd/server/main.go` (register adapters after + built-in init). + +At the end of Phase 2, installed plugin components appear in the registry and the API — but +executing them returns an error because the Plugin Host doesn't exist yet. + +### Phase 3: Plugin Host and JSON-RPC + +1. Implement the Plugin Host entry point in TypeScript (`plugin-host/src/index.ts`) — JSON-RPC + server over stdio, plugin loader, activation lifecycle. +2. Implement `@superplane/sdk` — the API module that plugins import. Context proxy objects that + translate method calls into RPC requests back to the Go server. +3. Implement the Go-side RPC client (`pkg/plugins/rpc.go`) — spawn the Node.js process, + send/receive JSON-RPC messages, handle context callbacks. +4. Connect the adapters to the RPC client so execution methods delegate to the Plugin Host. +5. Implement execution timeout enforcement on the Go side. +6. Implement lazy activation — track which plugins are activated, trigger activation on first + use. +7. Handle Plugin Host crashes — detection, restart, re-activation. + +At the end of Phase 3, plugins can be packaged, installed, and executed end-to-end. + +### Phase 4: Canvas Integration and Hardening + +1. Add "Plugins" section to the component/trigger picker in the frontend. +2. Add unit tests for manifest parsing, adapter behavior, RPC protocol, and packaging CLI. +3. Add E2E tests for a sample plugin in a workflow. +4. Document plugin authoring guide, SDK reference, and deployment instructions. +5. Publish `@superplane/sdk` type definitions as an npm package for plugin development. + +### Phase 5: In-App Plugin Builder + +1. Create `scripts` database table and migration. +2. Define `protos/scripts.proto` with CRUD + Generate RPCs. Regenerate protobuf, OpenAPI spec, + and SDKs. +3. Implement gRPC actions for the `Scripts` service in `pkg/grpc/actions/scripts/`. +4. Implement `pkg/models/script.go` — database model with CRUD operations. +5. Add `plugin/activateInline` RPC method to the Plugin Host for evaluating source code strings + (using Node.js `vm` module) instead of `require()`. +6. Extend the Plugin Manager to load scripts from the database at startup, register their + contributions, and activate them via `plugin/activateInline`. +7. Implement AI generation backend — proxy chat messages to OpenAI, maintain per-script chat + history, include `@superplane/sdk` reference in the system prompt. +8. Build the Script Builder UI page in `web_src/` — three-panel layout with script list, AI + chat, and code editor. +9. Add authorization rules for the new `Scripts` endpoints in + `pkg/authorization/interceptor.go`. +10. Add E2E tests for creating, editing, and executing an in-app script. + +At the end of Phase 5, users can create simple components and triggers from the UI without any +external tooling. + +## Security Considerations + +- **Process isolation.** Plugins run in a separate Node.js process. A crashing or misbehaving + plugin cannot corrupt the Go server's memory or state. +- **Controlled context access.** Plugin code cannot access the database, file system, or + internal Go APIs directly. All platform interactions go through the JSON-RPC protocol, which + exposes only the same context interfaces that built-in components use. +- **Secret access.** Plugins access secrets through `ctx.secrets.getKey()`, which delegates to + the Go server's `SecretsContext`. Secrets are transmitted over the local stdio pipe (not a + network socket) and are never logged. +- **HTTP request controls.** HTTP requests from plugins go through the Go server's managed HTTP + client (via `ctx/http.request` RPC), inheriting connection pooling, TLS settings, and rate + limits. Plugins can also make direct HTTP calls from Node.js — network policy enforcement is + a future consideration. +- **Resource limits.** Execution timeouts, memory limits, and request caps prevent a single + plugin from consuming unbounded resources. +- **Trust model.** Installed plugins are `.spx` archives explicitly installed by the operator + via the CLI. The operator controls which `.spx` files are installed — the same trust model as + built-in Go components. In-app scripts are created by authenticated users within their + organization. They run through the same Plugin Host with the same context isolation, but + authorization for creating/editing scripts is governed by the organization's role-based access + control. +- **In-app script isolation.** Scripts created in the UI run in the same Plugin Host process as + installed plugins. They cannot access other organizations' data because the context callbacks + (`ctx/secrets.*`, `ctx/metadata.*`, etc.) are scoped to the calling organization. Scripts + cannot import arbitrary npm packages — only `@superplane/sdk` is available as a built-in + module. + +## Decisions + +- **Distribution format**: Plugins are packaged as `.spx` archives (zip files containing + `package.json` + bundled `extension.js`) and installed via a CLI command. The server never + reads source files, `node_modules`, or build artifacts — only the pre-built bundle from the + archive. +- **Bundling**: The packaging CLI uses esbuild to produce a single `extension.js` with all npm + dependencies inlined. This eliminates `node_modules` from the installed plugin, keeps the + archive small, and makes loading fast (one `require()` call, no module resolution). +- **Runtime**: Node.js child process (Plugin Host) for full language support, npm ecosystem + access, native async/await, and TypeScript compatibility — at the cost of a cross-process + communication layer. +- **Communication**: JSON-RPC 2.0 over stdio. Simple, well-understood protocol. No need for + gRPC or HTTP between the processes — stdio is the lowest-latency local IPC option and + requires no port allocation. +- **Single Plugin Host**: All plugins share one Node.js process. This keeps resource usage + predictable. If isolation between plugins becomes important, we can move to one process per + plugin later. +- **Manifest-driven registration**: Metadata is read from `package.json` without executing + plugin code. This means the Go server knows about all contributions at startup, even for + plugins that haven't been activated yet. +- **Lazy activation**: Plugins activate on first use. This keeps startup fast and memory low + when only a subset of installed plugins are needed. +- **TypeScript-first**: The `@superplane/sdk` ships TypeScript definitions. Plugins can be + written in JavaScript, but the primary authoring experience targets TypeScript. +- **Naming**: Plugin contributions use dot-separated names. No special prefix like `js.` — the + name reflects the plugin's domain, not its implementation language. +- **Installed plugin scope**: Like built-in components, installed plugin contributions are + available to all organizations on the instance. +- **In-app script scope**: In-app scripts are organization-scoped. They are visible and usable + only within the organization that created them. This allows different organizations on the + same instance to have independent custom components without interfering with each other. +- **No file watching**: There is no file watcher polling for changes. Plugins are installed and + uninstalled explicitly via the CLI, which signals the server to reload. This is simpler and + more predictable than watching directories for changes. +- **Inline activation**: In-app scripts use `plugin/activateInline` instead of `require()`. + The Plugin Host evaluates the source code string using Node.js `vm` module, keeping the same + activation lifecycle as file-based plugins but without needing the code on the filesystem. +- **AI generation**: The in-app builder uses server-side LLM proxying rather than client-side + API calls. This keeps the API key server-side, allows rate limiting, and enables the server + to inject an up-to-date system prompt with the SDK reference. diff --git a/examples/plugins/superplane-plugin-github-issues/package-lock.json b/examples/plugins/superplane-plugin-github-issues/package-lock.json new file mode 100644 index 0000000000..9d7b406c00 --- /dev/null +++ b/examples/plugins/superplane-plugin-github-issues/package-lock.json @@ -0,0 +1,50 @@ +{ + "name": "superplane-plugin-github-issues", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "superplane-plugin-github-issues", + "version": "1.0.0", + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + }, + "engines": { + "superplane": "^1.0.0" + } + }, + "node_modules/@types/node": { + "version": "22.19.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", + "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/examples/plugins/superplane-plugin-github-issues/package.json b/examples/plugins/superplane-plugin-github-issues/package.json new file mode 100644 index 0000000000..5604538b29 --- /dev/null +++ b/examples/plugins/superplane-plugin-github-issues/package.json @@ -0,0 +1,109 @@ +{ + "name": "superplane-plugin-github-issues", + "version": "1.0.0", + "description": "Create and listen for GitHub issues using GitHub App authentication", + "main": "dist/index.js", + "engines": { + "superplane": "^1.0.0" + }, + "scripts": { + "build": "tsc" + }, + "superplane": { + "integration": { + "name": "github-issues", + "label": "GitHub Issues", + "icon": "github", + "description": "Create and listen for GitHub issues", + "hasWebhookHandler": true, + "configuration": [ + { + "name": "organization", + "label": "Organization", + "type": "string", + "description": "Organization to install the app into. If not specified, the app will be installed into the user's account." + } + ] + }, + "activationEvents": [ + "onComponent:github-issues.create-issue", + "onTrigger:github-issues.on-issue-created" + ], + "contributes": { + "components": [ + { + "name": "github-issues.create-issue", + "label": "Create Issue", + "description": "Create a new issue in a GitHub repository", + "icon": "github", + "color": "gray", + "configuration": [ + { + "name": "repository", + "label": "Repository", + "type": "integration-resource", + "required": true, + "typeOptions": { + "resource": { + "type": "repository", + "useNameAsValue": true + } + } + }, + { "name": "title", "label": "Title", "type": "string", "required": true }, + { "name": "body", "label": "Body", "type": "text" }, + { "name": "assignees", "label": "Assignees", "type": "list", "typeOptions": { "list": { "itemLabel": "Assignee", "itemDefinition": { "type": "string" } } } }, + { "name": "labels", "label": "Labels", "type": "list", "typeOptions": { "list": { "itemLabel": "Label", "itemDefinition": { "type": "string" } } } } + ], + "outputChannels": [ + { "name": "default", "label": "Default" } + ] + } + ], + "triggers": [ + { + "name": "github-issues.on-issue-created", + "label": "On Issue Created", + "description": "Fires when a new issue is opened in a GitHub repository", + "icon": "github", + "color": "gray", + "configuration": [ + { + "name": "repository", + "label": "Repository", + "type": "integration-resource", + "required": true, + "typeOptions": { + "resource": { + "type": "repository", + "useNameAsValue": true + } + } + } + ], + "exampleData": { + "action": "opened", + "issue": { + "number": 42, + "title": "Bug: login page returns 500", + "body": "Steps to reproduce...", + "state": "open", + "html_url": "https://github.com/acme/app/issues/42", + "user": { "login": "octocat" }, + "labels": [{ "name": "bug" }], + "created_at": "2026-02-20T10:30:00Z" + }, + "repository": { + "full_name": "acme/app" + } + } + } + ], + "integrations": [] + } + }, + "devDependencies": { + "typescript": "^5.8.0", + "@types/node": "^22.0.0" + } +} diff --git a/examples/plugins/superplane-plugin-github-issues/src/index.ts b/examples/plugins/superplane-plugin-github-issues/src/index.ts new file mode 100644 index 0000000000..96672072ce --- /dev/null +++ b/examples/plugins/superplane-plugin-github-issues/src/index.ts @@ -0,0 +1,525 @@ +import * as superplane from "@superplane/sdk"; +import * as crypto from "crypto"; + +const PEM_SECRET = "pem"; +const CLIENT_SECRET = "clientSecret"; +const WEBHOOK_SECRET = "webhookSecret"; + +interface AppMetadata { + installationId?: string; + state?: string; + owner?: string; + repositories?: Array<{ id: number; name: string; url: string }>; + githubApp?: { id: number; slug: string; clientId: string }; +} + +// --- GitHub App JWT auth --- + +function createJWT(appId: number, pem: string): string { + const header = Buffer.from( + JSON.stringify({ alg: "RS256", typ: "JWT" }) + ).toString("base64url"); + + const now = Math.floor(Date.now() / 1000); + const payload = Buffer.from( + JSON.stringify({ iat: now - 60, exp: now + 600, iss: appId }) + ).toString("base64url"); + + const signature = crypto + .createSign("RSA-SHA256") + .update(`${header}.${payload}`) + .sign(pem, "base64url"); + + return `${header}.${payload}.${signature}`; +} + +async function getInstallationToken( + http: superplane.HTTPClient, + appId: number, + installationId: string, + pem: string +): Promise { + const jwt = createJWT(appId, pem); + const resp = await http.request( + "POST", + `https://api.github.com/app/installations/${installationId}/access_tokens`, + { + headers: { + Authorization: `Bearer ${jwt}`, + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }, + } + ); + + if (resp.status !== 201) { + throw new Error( + `Failed to get installation token: ${resp.status} ${resp.body?.message}` + ); + } + + return resp.body.token; +} + +function findSecret( + secrets: Array<{ name: string; value: string }>, + name: string +): string { + const s = secrets.find((s) => s.name === name); + if (!s) throw new Error(`Secret '${name}' not found`); + return s.value; +} + +// --- Plugin activation --- + +export function activate(context: superplane.PluginContext) { + // Register the integration handler for the GitHub App lifecycle + context.integrations.register("github-issues", { + async sync(ctx) { + const metadata: AppMetadata = + (await ctx.integration.getMetadata()) || {}; + + if (metadata.installationId) { + return; + } + + const state = crypto.randomBytes(32).toString("base64url"); + const integrationId = await ctx.integration.id(); + + const config = ctx.configuration || {}; + const org = config.organization || ""; + + const manifest = JSON.stringify({ + name: "SuperPlane GH integration", + public: false, + url: "https://superplane.com", + default_permissions: { + issues: "write", + repository_hooks: "write", + }, + default_events: ["issues"], + setup_url: `${ctx.baseUrl}/api/v1/integrations/${integrationId}/setup`, + redirect_url: `${ctx.baseUrl}/api/v1/integrations/${integrationId}/redirect`, + hook_attributes: { + url: `${ctx.webhooksBaseUrl}/api/v1/integrations/${integrationId}/webhook`, + }, + }); + + const browserUrl = org + ? `https://github.com/organizations/${org}/settings/apps/new` + : "https://github.com/settings/apps/new"; + + await ctx.integration.newBrowserAction({ + description: `To complete the GitHub app setup:\n\n1. The "**Continue**" button/link will take you to GitHub with the app manifest pre-filled.\n2. **Create GitHub App**: Give the new app a name, and click the "Create" button.\n3. **Install GitHub App**: Install the new GitHub app in the user/organization.`, + url: browserUrl, + method: "POST", + formFields: { manifest, state }, + }); + + await ctx.integration.setMetadata({ owner: org, state }); + }, + + async handleRequest(ctx) { + const metadata: AppMetadata = + (await ctx.integration.getMetadata()) || {}; + + if (ctx.request.path.endsWith("/redirect")) { + return handleAfterAppCreation(ctx, metadata); + } + + if (ctx.request.path.endsWith("/setup")) { + return handleAfterAppInstallation(ctx, metadata); + } + + if (ctx.request.path.endsWith("/webhook")) { + return handleIntegrationWebhook(ctx, metadata); + } + + return { action: "error", status: 404, message: "not found" }; + }, + + webhookHandler: { + async setup(ctx) { + const secrets = await ctx.integration.getSecrets(); + const pem = findSecret(secrets, PEM_SECRET); + const metadata: AppMetadata = + (await ctx.integration.getMetadata()) || {}; + + if (!metadata.githubApp || !metadata.installationId) { + throw new Error("GitHub App not configured"); + } + + const token = await getInstallationToken( + ctx.http, + metadata.githubApp.id, + metadata.installationId, + pem + ); + + const config = ctx.configuration as { + eventType?: string; + repository?: string; + }; + + const resp = await ctx.http.request( + "POST", + `https://api.github.com/repos/${metadata.owner}/${config.repository}/hooks`, + { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/vnd.github+json", + "Content-Type": "application/json", + "X-GitHub-Api-Version": "2022-11-28", + }, + body: JSON.stringify({ + active: true, + events: [config.eventType || "issues"], + config: { + url: ctx.webhookUrl, + secret: ctx.webhookSecret, + content_type: "json", + }, + }), + } + ); + + if (resp.status !== 201) { + throw new Error( + `Failed to create webhook: ${resp.status} ${resp.body?.message}` + ); + } + + return { id: resp.body.id, name: resp.body.name }; + }, + + async cleanup(ctx) { + const secrets = await ctx.integration.getSecrets(); + const pem = findSecret(secrets, PEM_SECRET); + const metadata: AppMetadata = + (await ctx.integration.getMetadata()) || {}; + + if (!metadata.githubApp || !metadata.installationId) { + return; + } + + const token = await getInstallationToken( + ctx.http, + metadata.githubApp.id, + metadata.installationId, + pem + ); + + const config = ctx.configuration as { repository?: string }; + const webhookMeta = ctx.webhookMetadata as { id?: number }; + + if (!webhookMeta?.id) return; + + await ctx.http.request( + "DELETE", + `https://api.github.com/repos/${metadata.owner}/${config.repository}/hooks/${webhookMeta.id}`, + { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }, + } + ); + }, + + async compareConfig(a: any, b: any) { + return a?.repository === b?.repository && a?.eventType === b?.eventType; + }, + }, + }); + + // Register the create-issue component + context.components.register("github-issues.create-issue", { + async setup(ctx) { + // Validation only -- ensure repo is accessible + }, + + async execute(ctx) { + const secrets = await ctx.integration.getSecrets(); + const pem = findSecret(secrets, PEM_SECRET); + const metadata: AppMetadata = + (await ctx.integration.getMetadata()) || {}; + + if (!metadata.githubApp || !metadata.installationId) { + ctx.fail("not_configured", "GitHub App is not configured"); + return; + } + + const token = await getInstallationToken( + ctx.http, + metadata.githubApp.id, + metadata.installationId, + pem + ); + + const config = ctx.configuration; + const resp = await ctx.http.request( + "POST", + `https://api.github.com/repos/${metadata.owner}/${config.repository}/issues`, + { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/vnd.github+json", + "Content-Type": "application/json", + "X-GitHub-Api-Version": "2022-11-28", + }, + body: JSON.stringify({ + title: config.title, + body: config.body || "", + assignees: config.assignees || [], + labels: config.labels || [], + }), + } + ); + + if (resp.status !== 201) { + ctx.fail( + "api_error", + `GitHub API returned ${resp.status}: ${resp.body?.message}` + ); + return; + } + + ctx.emit("default", "github.issue", resp.body); + }, + }); + + // Register the on-issue-created trigger + context.triggers.register("github-issues.on-issue-created", { + async setup(ctx) { + const config = ctx.configuration as { repository?: string }; + if (!config.repository) { + throw new Error("repository is required"); + } + + await ctx.integration.requestWebhook({ + eventType: "issues", + repository: config.repository, + }); + }, + + async handleWebhook(ctx) { + const signature = ctx.headers["x-hub-signature-256"]; + const secret = await ctx.webhook.getSecret(); + + const expected = + "sha256=" + + crypto.createHmac("sha256", secret).update(ctx.body).digest("hex"); + + if (signature !== expected) { + return { status: 401 }; + } + + const payload = JSON.parse(ctx.body); + + if (payload.action !== "opened") { + return { status: 200 }; + } + + ctx.events.emit("github.issue", payload); + return { status: 200 }; + }, + }); +} + +export function deactivate() {} + +// --- Integration request handlers --- + +async function handleAfterAppCreation( + ctx: superplane.IntegrationRequestContext, + metadata: AppMetadata +): Promise { + const code = ctx.request.query.code; + const state = ctx.request.query.state; + + if (!code || !state || state !== metadata.state) { + return { action: "error", status: 400, message: "missing code or state" }; + } + + const resp = await ctx.http.request( + "POST", + `https://api.github.com/app-manifests/${code}/conversions`, + { + headers: { + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }, + } + ); + + if (resp.status !== 201) { + return { + action: "error", + status: 500, + message: `Failed to convert manifest: ${resp.body?.message}`, + }; + } + + const appData = resp.body; + + metadata.githubApp = { + id: appData.id, + slug: appData.slug, + clientId: appData.client_id, + }; + + await ctx.integration.setMetadata(metadata); + await ctx.integration.setSecret(CLIENT_SECRET, appData.client_secret); + await ctx.integration.setSecret(WEBHOOK_SECRET, appData.webhook_secret); + await ctx.integration.setSecret(PEM_SECRET, appData.pem); + + return { + action: "redirect", + url: `https://github.com/apps/${appData.slug}/installations/new?state=${state}`, + }; +} + +async function handleAfterAppInstallation( + ctx: superplane.IntegrationRequestContext, + metadata: AppMetadata +): Promise { + const integrationId = await ctx.integration.id(); + + if (metadata.installationId) { + return { + action: "redirect", + url: `${ctx.baseUrl}/${ctx.organizationId}/settings/integrations/${integrationId}`, + }; + } + + const installationId = ctx.request.query.installation_id; + const setupAction = ctx.request.query.setup_action; + const state = ctx.request.query.state; + + if (!installationId || state !== metadata.state) { + return { + action: "error", + status: 400, + message: "invalid installation ID or state", + }; + } + + if (setupAction !== "install") { + return { action: "json", status: 200, body: { ok: true } }; + } + + metadata.installationId = installationId; + + const secrets = await ctx.integration.getSecrets(); + const pem = findSecret(secrets, PEM_SECRET); + const token = await getInstallationToken( + ctx.http, + metadata.githubApp!.id, + installationId, + pem + ); + + if (!metadata.owner) { + const appResp = await ctx.http.request( + "GET", + `https://api.github.com/apps/${metadata.githubApp!.slug}`, + { + headers: { + Authorization: `Bearer ${createJWT(metadata.githubApp!.id, pem)}`, + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }, + } + ); + if (appResp.status === 200 && appResp.body?.owner?.login) { + metadata.owner = appResp.body.owner.login; + } + } + + const reposResp = await ctx.http.request( + "GET", + "https://api.github.com/installation/repositories", + { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }, + } + ); + + metadata.repositories = []; + if (reposResp.status === 200 && reposResp.body?.repositories) { + for (const r of reposResp.body.repositories) { + metadata.repositories.push({ + id: r.id, + name: r.name, + url: r.html_url, + }); + } + } + + metadata.state = ""; + await ctx.integration.setMetadata(metadata); + await ctx.integration.removeBrowserAction(); + await ctx.integration.ready(); + + return { + action: "redirect", + url: `${ctx.baseUrl}/${ctx.organizationId}/settings/integrations/${integrationId}`, + }; +} + +async function handleIntegrationWebhook( + ctx: superplane.IntegrationRequestContext, + metadata: AppMetadata +): Promise { + const secrets = await ctx.integration.getSecrets(); + let webhookSecret: string; + try { + webhookSecret = findSecret(secrets, WEBHOOK_SECRET); + } catch { + return { action: "error", status: 500, message: "webhook secret not found" }; + } + + const signature = ctx.request.headers["X-Hub-Signature-256"] || ctx.request.headers["x-hub-signature-256"] || ""; + const expected = + "sha256=" + + crypto + .createHmac("sha256", webhookSecret) + .update(ctx.request.body) + .digest("hex"); + + if (signature !== expected) { + return { action: "error", status: 400, message: "invalid signature" }; + } + + const event = JSON.parse(ctx.request.body); + const eventType = ctx.request.headers["X-GitHub-Event"] || ctx.request.headers["x-github-event"] || ""; + + if (eventType === "installation") { + const action = event.action; + if (action === "suspend") { + await ctx.integration.error("app installation was suspended"); + } else if (action === "unsuspend") { + await ctx.integration.ready(); + } else if (action === "deleted") { + metadata.installationId = ""; + metadata.repositories = []; + const state = crypto.randomBytes(32).toString("base64url"); + metadata.state = state; + await ctx.integration.setMetadata(metadata); + await ctx.integration.error("app installation was deleted"); + if (metadata.githubApp?.slug) { + await ctx.integration.newBrowserAction({ + description: `To complete the GitHub app setup:\n1. **Install GitHub App**: Install the new GitHub app in the user/organization.`, + url: `https://github.com/apps/${metadata.githubApp.slug}/installations/new?state=${state}`, + method: "GET", + }); + } + } + } + + return { action: "json", status: 200, body: { ok: true } }; +} diff --git a/examples/plugins/superplane-plugin-github-issues/tsconfig.json b/examples/plugins/superplane-plugin-github-issues/tsconfig.json new file mode 100644 index 0000000000..72edda959a --- /dev/null +++ b/examples/plugins/superplane-plugin-github-issues/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "lib": ["ES2022"], + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "sourceMap": true, + "baseUrl": ".", + "paths": { + "@superplane/sdk": ["../../../plugin-host/dist/sdk"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/pkg/ai/client.go b/pkg/ai/client.go new file mode 100644 index 0000000000..4e49bed7fe --- /dev/null +++ b/pkg/ai/client.go @@ -0,0 +1,191 @@ +package ai + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "regexp" + "strings" + "time" +) + +const defaultEndpoint = "https://api.openai.com/v1/chat/completions" +const defaultModel = "gpt-4o" + +var codeBlockRe = regexp.MustCompile("(?s)```(?:typescript|javascript|ts|js)?\\s*\\n(.*?)```") + +const systemPrompt = `You are a SuperPlane plugin code generator. You write TypeScript plugins that use the @superplane/sdk API. + +A SuperPlane plugin is a single file that exports an activate() function. The activate function receives a plugin context and uses it to register components and triggers. + +Example plugin structure: + +const superplane = require("@superplane/sdk"); + +export function activate(ctx) { + ctx.components.register("my-component", { + label: "My Component", + description: "Does something useful", + configuration: [ + { name: "param1", label: "Parameter 1", type: "string", required: true } + ], + outputChannels: [{ name: "default", label: "Default" }], + async execute(execCtx) { + const config = execCtx.configuration; + // Do work here using execCtx.http.request() for external API calls + const result = await execCtx.http.request({ + method: "POST", + url: "https://api.example.com/action", + headers: { "Authorization": "Bearer " + await execCtx.secrets.getKey("api-key") }, + body: JSON.stringify({ param: config.param1 }) + }); + execCtx.emit("default", { result: JSON.parse(result.body) }); + } + }); +} + +export function deactivate() {} + +Available context methods: +- ctx.components.register(name, handler) - Register a component +- ctx.triggers.register(name, handler) - Register a trigger +- execCtx.emit(channel, data) - Emit data to an output channel +- execCtx.pass() - Mark execution as passed +- execCtx.fail(reason, message) - Mark execution as failed +- execCtx.configuration - Access component configuration values +- execCtx.secrets.getKey(name) - Get a secret value +- execCtx.http.request({method, url, headers, body}) - Make HTTP requests +- execCtx.metadata.get(key) / execCtx.metadata.set(key, value) - Read/write metadata + +Rules: +- Always export activate() and deactivate() functions +- Use require("@superplane/sdk") for the SDK +- Keep the code in a single file +- Use async/await for asynchronous operations +- Include proper error handling +- Return the complete, runnable code +- When writing JSON objects or configuration objects, always format them with proper indentation (one key per line), never as a single long line +- NEVER use external npm packages (e.g. axios, node-fetch, telnet-client). Only built-in Node.js modules and @superplane/sdk are available. For HTTP requests, always use execCtx.http.request() + +When the user asks you to modify existing code, update the existing code rather than rewriting from scratch. +Respond with a brief explanation followed by the complete code in a typescript code block.` + +type Client struct { + apiKey string + endpoint string + model string + client *http.Client +} + +func NewClient(apiKey string) *Client { + return &Client{ + apiKey: apiKey, + endpoint: defaultEndpoint, + model: defaultModel, + client: &http.Client{ + Timeout: 60 * time.Second, + }, + } +} + +type chatMessage struct { + Role string `json:"role"` + Content string `json:"content"` +} + +type chatRequest struct { + Model string `json:"model"` + Messages []chatMessage `json:"messages"` +} + +type chatResponse struct { + Choices []struct { + Message chatMessage `json:"message"` + } `json:"choices"` + Error *struct { + Message string `json:"message"` + } `json:"error"` +} + +func (c *Client) GenerateScript(ctx context.Context, userMessage string, existingSource string) (string, string, error) { + messages := []chatMessage{ + {Role: "system", Content: systemPrompt}, + } + + if existingSource != "" { + messages = append(messages, chatMessage{ + Role: "user", + Content: fmt.Sprintf("Here is the current script code:\n```typescript\n%s\n```", existingSource), + }) + messages = append(messages, chatMessage{ + Role: "assistant", + Content: "I see the current code. What changes would you like me to make?", + }) + } + + messages = append(messages, chatMessage{ + Role: "user", + Content: userMessage, + }) + + reqBody := chatRequest{ + Model: c.model, + Messages: messages, + } + + bodyBytes, err := json.Marshal(reqBody) + if err != nil { + return "", "", fmt.Errorf("marshaling request: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "POST", c.endpoint, bytes.NewReader(bodyBytes)) + if err != nil { + return "", "", fmt.Errorf("creating request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+c.apiKey) + + resp, err := c.client.Do(req) + if err != nil { + return "", "", fmt.Errorf("sending request: %w", err) + } + defer resp.Body.Close() + + respBytes, err := io.ReadAll(resp.Body) + if err != nil { + return "", "", fmt.Errorf("reading response: %w", err) + } + + var chatResp chatResponse + if err := json.Unmarshal(respBytes, &chatResp); err != nil { + return "", "", fmt.Errorf("parsing response: %w", err) + } + + if chatResp.Error != nil { + return "", "", fmt.Errorf("API error: %s", chatResp.Error.Message) + } + + if len(chatResp.Choices) == 0 { + return "", "", fmt.Errorf("no response from AI") + } + + fullResponse := chatResp.Choices[0].Message.Content + source := extractCode(fullResponse) + + return fullResponse, source, nil +} + +func extractCode(response string) string { + matches := codeBlockRe.FindAllStringSubmatch(response, -1) + if len(matches) == 0 { + return "" + } + + // Return the last code block (most likely the complete code) + lastMatch := matches[len(matches)-1] + return strings.TrimSpace(lastMatch[1]) +} diff --git a/pkg/authorization/interceptor.go b/pkg/authorization/interceptor.go index 231937b0d3..57267bf463 100644 --- a/pkg/authorization/interceptor.go +++ b/pkg/authorization/interceptor.go @@ -10,6 +10,7 @@ import ( pbGroups "github.com/superplanehq/superplane/pkg/protos/groups" pbOrganization "github.com/superplanehq/superplane/pkg/protos/organizations" pbRoles "github.com/superplanehq/superplane/pkg/protos/roles" + pbScripts "github.com/superplanehq/superplane/pkg/protos/scripts" pbSecrets "github.com/superplanehq/superplane/pkg/protos/secrets" pbServiceAccounts "github.com/superplanehq/superplane/pkg/protos/service_accounts" pbUsers "github.com/superplanehq/superplane/pkg/protos/users" @@ -123,6 +124,14 @@ func NewAuthorizationInterceptor(authService Authorization) *AuthorizationInterc pbServiceAccounts.ServiceAccounts_UpdateServiceAccount_FullMethodName: {Resource: "service_accounts", Action: "update", DomainType: models.DomainTypeOrganization}, pbServiceAccounts.ServiceAccounts_DeleteServiceAccount_FullMethodName: {Resource: "service_accounts", Action: "delete", DomainType: models.DomainTypeOrganization}, pbServiceAccounts.ServiceAccounts_RegenerateServiceAccountToken_FullMethodName: {Resource: "service_accounts", Action: "update", DomainType: models.DomainTypeOrganization}, + + // Scripts rules + pbScripts.Scripts_ListScripts_FullMethodName: {Resource: "scripts", Action: "read", DomainType: models.DomainTypeOrganization}, + pbScripts.Scripts_DescribeScript_FullMethodName: {Resource: "scripts", Action: "read", DomainType: models.DomainTypeOrganization}, + pbScripts.Scripts_CreateScript_FullMethodName: {Resource: "scripts", Action: "create", DomainType: models.DomainTypeOrganization}, + pbScripts.Scripts_UpdateScript_FullMethodName: {Resource: "scripts", Action: "update", DomainType: models.DomainTypeOrganization}, + pbScripts.Scripts_DeleteScript_FullMethodName: {Resource: "scripts", Action: "delete", DomainType: models.DomainTypeOrganization}, + pbScripts.Scripts_GenerateScript_FullMethodName: {Resource: "scripts", Action: "update", DomainType: models.DomainTypeOrganization}, } return &AuthorizationInterceptor{ diff --git a/pkg/cli/commands/plugins/install.go b/pkg/cli/commands/plugins/install.go new file mode 100644 index 0000000000..c8fad82216 --- /dev/null +++ b/pkg/cli/commands/plugins/install.go @@ -0,0 +1,225 @@ +package plugins + +import ( + "archive/zip" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "syscall" + "time" + + "github.com/spf13/cobra" + "github.com/superplanehq/superplane/pkg/plugins" +) + +func newInstallCommand() *cobra.Command { + return &cobra.Command{ + Use: "install ", + Short: "Install a plugin from a .spx archive", + Args: cobra.ExactArgs(1), + RunE: runInstall, + } +} + +func runInstall(cmd *cobra.Command, args []string) error { + spxPath := args[0] + + pluginsDir := os.Getenv("SUPERPLANE_PLUGINS_DIR") + if pluginsDir == "" { + pluginsDir = "plugins" + } + + if err := os.MkdirAll(pluginsDir, 0755); err != nil { + return fmt.Errorf("creating plugins directory: %w", err) + } + + // Extract to a temp directory first to read the manifest + tmpDir, err := os.MkdirTemp("", "spx-install-*") + if err != nil { + return fmt.Errorf("creating temp directory: %w", err) + } + defer os.RemoveAll(tmpDir) + + if err := extractZip(spxPath, tmpDir); err != nil { + return fmt.Errorf("extracting .spx archive: %w", err) + } + + manifest, err := plugins.ParseManifest(tmpDir) + if err != nil { + return fmt.Errorf("reading manifest: %w", err) + } + + if err := plugins.ValidateManifest(manifest); err != nil { + return fmt.Errorf("invalid manifest: %w", err) + } + + // Check that extension.js exists in the archive + extensionPath := filepath.Join(tmpDir, "extension.js") + if _, err := os.Stat(extensionPath); os.IsNotExist(err) { + return fmt.Errorf("archive is missing extension.js") + } + + // Move to final destination + destDir := filepath.Join(pluginsDir, manifest.Name) + + // Remove old version if exists + if _, err := os.Stat(destDir); err == nil { + if err := os.RemoveAll(destDir); err != nil { + return fmt.Errorf("removing old version: %w", err) + } + } + + if err := os.Rename(tmpDir, destDir); err != nil { + // os.Rename may fail across filesystems, fall back to copy + if err := copyDir(tmpDir, destDir); err != nil { + return fmt.Errorf("installing plugin: %w", err) + } + } + + // Update plugins.json + pj, err := plugins.ReadPluginsJSON(pluginsDir) + if err != nil { + return fmt.Errorf("reading plugins.json: %w", err) + } + + // Remove existing entry for this plugin name + filtered := make([]plugins.PluginRecord, 0, len(pj.Plugins)) + for _, p := range pj.Plugins { + if p.Name != manifest.Name { + filtered = append(filtered, p) + } + } + + filtered = append(filtered, plugins.PluginRecord{ + Name: manifest.Name, + Version: manifest.Version, + InstalledAt: time.Now().UTC(), + }) + + pj.Plugins = filtered + + if err := plugins.WritePluginsJSON(pluginsDir, pj); err != nil { + return fmt.Errorf("writing plugins.json: %w", err) + } + + fmt.Fprintf(cmd.OutOrStdout(), "Installed %s v%s\n", manifest.Name, manifest.Version) + + for _, c := range manifest.SuperPlane.Contributes.Components { + fmt.Fprintf(cmd.OutOrStdout(), " Registered component: %s\n", c.Name) + } + for _, t := range manifest.SuperPlane.Contributes.Triggers { + fmt.Fprintf(cmd.OutOrStdout(), " Registered trigger: %s\n", t.Name) + } + + // Signal the server to reload + signalServer(cmd) + + return nil +} + +func extractZip(zipPath, destDir string) error { + r, err := zip.OpenReader(zipPath) + if err != nil { + return err + } + defer r.Close() + + for _, f := range r.File { + fpath := filepath.Join(destDir, f.Name) + + if !strings.HasPrefix(fpath, filepath.Clean(destDir)+string(os.PathSeparator)) { + return fmt.Errorf("illegal file path in archive: %s", f.Name) + } + + if f.FileInfo().IsDir() { + os.MkdirAll(fpath, os.ModePerm) + continue + } + + if err := os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil { + return err + } + + outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + if err != nil { + return err + } + + rc, err := f.Open() + if err != nil { + outFile.Close() + return err + } + + _, err = io.Copy(outFile, rc) + rc.Close() + outFile.Close() + + if err != nil { + return err + } + } + + return nil +} + +func copyDir(src, dst string) error { + return filepath.Walk(src, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + relPath, err := filepath.Rel(src, path) + if err != nil { + return err + } + + dstPath := filepath.Join(dst, relPath) + + if info.IsDir() { + return os.MkdirAll(dstPath, info.Mode()) + } + + data, err := os.ReadFile(path) + if err != nil { + return err + } + + return os.WriteFile(dstPath, data, info.Mode()) + }) +} + +func signalServer(cmd *cobra.Command) { + pidFile := os.Getenv("SUPERPLANE_PID_FILE") + if pidFile == "" { + fmt.Fprintln(cmd.OutOrStdout(), "Restart the server to load the plugin.") + return + } + + data, err := os.ReadFile(pidFile) + if err != nil { + fmt.Fprintf(cmd.OutOrStdout(), "Restart the server to load the plugin.\n") + return + } + + var pid int + if _, err := fmt.Sscanf(strings.TrimSpace(string(data)), "%d", &pid); err != nil { + fmt.Fprintf(cmd.OutOrStdout(), "Restart the server to load the plugin.\n") + return + } + + proc, err := os.FindProcess(pid) + if err != nil { + fmt.Fprintf(cmd.OutOrStdout(), "Restart the server to load the plugin.\n") + return + } + + if err := proc.Signal(syscall.SIGHUP); err != nil { + fmt.Fprintf(cmd.OutOrStdout(), "Restart the server to load the plugin.\n") + return + } + + fmt.Fprintln(cmd.OutOrStdout(), "Server reloaded.") +} diff --git a/pkg/cli/commands/plugins/list.go b/pkg/cli/commands/plugins/list.go new file mode 100644 index 0000000000..cc37654662 --- /dev/null +++ b/pkg/cli/commands/plugins/list.go @@ -0,0 +1,43 @@ +package plugins + +import ( + "fmt" + "os" + "text/tabwriter" + + "github.com/spf13/cobra" + "github.com/superplanehq/superplane/pkg/plugins" +) + +func newListCommand() *cobra.Command { + return &cobra.Command{ + Use: "list", + Short: "List installed plugins", + Args: cobra.NoArgs, + RunE: runList, + } +} + +func runList(cmd *cobra.Command, args []string) error { + pluginsDir := os.Getenv("SUPERPLANE_PLUGINS_DIR") + if pluginsDir == "" { + pluginsDir = "plugins" + } + + pj, err := plugins.ReadPluginsJSON(pluginsDir) + if err != nil { + return fmt.Errorf("reading plugins.json: %w", err) + } + + if len(pj.Plugins) == 0 { + fmt.Fprintln(cmd.OutOrStdout(), "No plugins installed") + return nil + } + + w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 2, ' ', 0) + fmt.Fprintln(w, "NAME\tVERSION\tINSTALLED") + for _, p := range pj.Plugins { + fmt.Fprintf(w, "%s\t%s\t%s\n", p.Name, p.Version, p.InstalledAt.Format("2006-01-02 15:04:05")) + } + return w.Flush() +} diff --git a/pkg/cli/commands/plugins/pack.go b/pkg/cli/commands/plugins/pack.go new file mode 100644 index 0000000000..ede56f6018 --- /dev/null +++ b/pkg/cli/commands/plugins/pack.go @@ -0,0 +1,139 @@ +package plugins + +import ( + "archive/zip" + "fmt" + "os" + "os/exec" + "path/filepath" + + "github.com/spf13/cobra" + pluginspkg "github.com/superplanehq/superplane/pkg/plugins" +) + +func newPackCommand() *cobra.Command { + return &cobra.Command{ + Use: "pack [directory]", + Short: "Package a plugin into a .spx archive", + Long: "Bundle and package a plugin project into a .spx archive for distribution. Defaults to the current directory.", + Args: cobra.MaximumNArgs(1), + RunE: runPack, + } +} + +func runPack(cmd *cobra.Command, args []string) error { + dir := "." + if len(args) > 0 { + dir = args[0] + } + + absDir, err := filepath.Abs(dir) + if err != nil { + return fmt.Errorf("resolving directory: %w", err) + } + + manifest, err := pluginspkg.ParseManifest(absDir) + if err != nil { + return fmt.Errorf("reading manifest: %w", err) + } + + if err := pluginspkg.ValidateManifest(manifest); err != nil { + return fmt.Errorf("invalid manifest: %w", err) + } + + // Bundle with esbuild + mainFile := manifest.Main + if mainFile == "" { + mainFile = "dist/index.js" + } + + mainPath := filepath.Join(absDir, mainFile) + if _, err := os.Stat(mainPath); os.IsNotExist(err) { + // Try building first + fmt.Fprintln(cmd.OutOrStdout(), "Building plugin...") + buildCmd := exec.Command("npm", "run", "build") + buildCmd.Dir = absDir + buildCmd.Stdout = cmd.OutOrStdout() + buildCmd.Stderr = cmd.OutOrStderr() + if err := buildCmd.Run(); err != nil { + return fmt.Errorf("build failed: %w", err) + } + + if _, err := os.Stat(mainPath); os.IsNotExist(err) { + return fmt.Errorf("build did not produce %s", mainFile) + } + } + + bundlePath := filepath.Join(absDir, "extension.js") + + fmt.Fprintln(cmd.OutOrStdout(), "Bundling with esbuild...") + esbuildCmd := exec.Command("npx", "esbuild", + mainPath, + "--bundle", + "--platform=node", + "--target=node18", + "--format=cjs", + "--external:@superplane/sdk", + fmt.Sprintf("--outfile=%s", bundlePath), + ) + esbuildCmd.Dir = absDir + esbuildCmd.Stdout = cmd.OutOrStdout() + esbuildCmd.Stderr = cmd.OutOrStderr() + + if err := esbuildCmd.Run(); err != nil { + return fmt.Errorf("esbuild bundling failed: %w", err) + } + defer os.Remove(bundlePath) + + // Create .spx archive + archiveName := fmt.Sprintf("%s-%s.spx", manifest.Name, manifest.Version) + archivePath := filepath.Join(absDir, archiveName) + + if err := createSpxArchive(archivePath, absDir, bundlePath); err != nil { + return fmt.Errorf("creating .spx archive: %w", err) + } + + fmt.Fprintf(cmd.OutOrStdout(), "Created %s\n", archiveName) + return nil +} + +func createSpxArchive(archivePath, projectDir, bundlePath string) error { + outFile, err := os.Create(archivePath) + if err != nil { + return err + } + defer outFile.Close() + + w := zip.NewWriter(outFile) + defer w.Close() + + // Add package.json + packageJSON, err := os.ReadFile(filepath.Join(projectDir, "package.json")) + if err != nil { + return fmt.Errorf("reading package.json: %w", err) + } + + pjWriter, err := w.Create("package.json") + if err != nil { + return err + } + if _, err := pjWriter.Write(packageJSON); err != nil { + return err + } + + // Add extension.js + extensionJS, err := os.ReadFile(bundlePath) + if err != nil { + return fmt.Errorf("reading extension.js: %w", err) + } + + ejWriter, err := w.Create("extension.js") + if err != nil { + return err + } + if _, err := ejWriter.Write(extensionJS); err != nil { + return err + } + + return nil +} diff --git a/pkg/cli/commands/plugins/root.go b/pkg/cli/commands/plugins/root.go new file mode 100644 index 0000000000..ab4a6a484c --- /dev/null +++ b/pkg/cli/commands/plugins/root.go @@ -0,0 +1,20 @@ +package plugins + +import ( + "github.com/spf13/cobra" +) + +func NewCommand() *cobra.Command { + root := &cobra.Command{ + Use: "plugin", + Short: "Manage SuperPlane plugins", + Aliases: []string{"plugins"}, + } + + root.AddCommand(newInstallCommand()) + root.AddCommand(newUninstallCommand()) + root.AddCommand(newListCommand()) + root.AddCommand(newPackCommand()) + + return root +} diff --git a/pkg/cli/commands/plugins/uninstall.go b/pkg/cli/commands/plugins/uninstall.go new file mode 100644 index 0000000000..1e7e984e0d --- /dev/null +++ b/pkg/cli/commands/plugins/uninstall.go @@ -0,0 +1,63 @@ +package plugins + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/spf13/cobra" + "github.com/superplanehq/superplane/pkg/plugins" +) + +func newUninstallCommand() *cobra.Command { + return &cobra.Command{ + Use: "uninstall ", + Short: "Uninstall a plugin", + Args: cobra.ExactArgs(1), + RunE: runUninstall, + } +} + +func runUninstall(cmd *cobra.Command, args []string) error { + pluginName := args[0] + + pluginsDir := os.Getenv("SUPERPLANE_PLUGINS_DIR") + if pluginsDir == "" { + pluginsDir = "plugins" + } + + pj, err := plugins.ReadPluginsJSON(pluginsDir) + if err != nil { + return fmt.Errorf("reading plugins.json: %w", err) + } + + found := false + filtered := make([]plugins.PluginRecord, 0, len(pj.Plugins)) + for _, p := range pj.Plugins { + if p.Name == pluginName { + found = true + continue + } + filtered = append(filtered, p) + } + + if !found { + return fmt.Errorf("plugin %q is not installed", pluginName) + } + + pluginDir := filepath.Join(pluginsDir, pluginName) + if err := os.RemoveAll(pluginDir); err != nil { + return fmt.Errorf("removing plugin directory: %w", err) + } + + pj.Plugins = filtered + if err := plugins.WritePluginsJSON(pluginsDir, pj); err != nil { + return fmt.Errorf("writing plugins.json: %w", err) + } + + fmt.Fprintf(cmd.OutOrStdout(), "Uninstalled %s\n", pluginName) + + signalServer(cmd) + + return nil +} diff --git a/pkg/cli/root.go b/pkg/cli/root.go index 40055d9633..f2d8d2efb9 100644 --- a/pkg/cli/root.go +++ b/pkg/cli/root.go @@ -15,6 +15,7 @@ import ( executions "github.com/superplanehq/superplane/pkg/cli/commands/executions" index "github.com/superplanehq/superplane/pkg/cli/commands/index" integrations "github.com/superplanehq/superplane/pkg/cli/commands/integrations" + pluginscmd "github.com/superplanehq/superplane/pkg/cli/commands/plugins" queue "github.com/superplanehq/superplane/pkg/cli/commands/queue" secrets "github.com/superplanehq/superplane/pkg/cli/commands/secrets" "github.com/superplanehq/superplane/pkg/cli/core" @@ -58,6 +59,7 @@ func init() { RootCmd.AddCommand(integrations.NewCommand(options)) RootCmd.AddCommand(queue.NewCommand(options)) RootCmd.AddCommand(secrets.NewCommand(options)) + RootCmd.AddCommand(pluginscmd.NewCommand()) } func initConfig() { diff --git a/pkg/core/component.go b/pkg/core/component.go index c178825673..6c3b0bab17 100644 --- a/pkg/core/component.go +++ b/pkg/core/component.go @@ -180,6 +180,7 @@ type SetupContext struct { Auth AuthContext Integration IntegrationContext Webhook NodeWebhookContext + Secrets SecretsContext } /* diff --git a/pkg/core/trigger.go b/pkg/core/trigger.go index 0e86340fa0..b21f10d4a2 100644 --- a/pkg/core/trigger.go +++ b/pkg/core/trigger.go @@ -90,6 +90,7 @@ type TriggerContext struct { Events EventContext Webhook NodeWebhookContext Integration IntegrationContext + Secrets SecretsContext } type EventContext interface { diff --git a/pkg/grpc/actions/canvases/update_canvas.go b/pkg/grpc/actions/canvases/update_canvas.go index 64c03902d0..b62a289500 100644 --- a/pkg/grpc/actions/canvases/update_canvas.go +++ b/pkg/grpc/actions/canvases/update_canvas.go @@ -94,7 +94,7 @@ func UpdateCanvas(ctx context.Context, encryptor crypto.Encryptor, registry *reg } if workflowNode.State == models.CanvasNodeStateReady { - err = setupNode(ctx, tx, encryptor, registry, workflowNode, webhookBaseURL) + err = setupNode(ctx, tx, encryptor, registry, workflowNode, webhookBaseURL, existingCanvas.OrganizationID) if err != nil { workflowNode.State = models.CanvasNodeStateError errorMsg := err.Error() @@ -307,12 +307,12 @@ func upsertNode(tx *gorm.DB, existingNodes []models.CanvasNode, node models.Node return &canvasNode, nil } -func setupNode(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, registry *registry.Registry, node *models.CanvasNode, webhookBaseURL string) error { +func setupNode(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, registry *registry.Registry, node *models.CanvasNode, webhookBaseURL string, organizationID uuid.UUID) error { switch node.Type { case models.NodeTypeTrigger: - return setupTrigger(ctx, tx, encryptor, registry, node, webhookBaseURL) + return setupTrigger(ctx, tx, encryptor, registry, node, webhookBaseURL, organizationID) case models.NodeTypeComponent: - return setupComponent(ctx, tx, encryptor, registry, node, webhookBaseURL) + return setupComponent(ctx, tx, encryptor, registry, node, webhookBaseURL, organizationID) case models.NodeTypeWidget: // Widgets are not persisted and don't have any logic to execute and to setup. return nil @@ -321,7 +321,7 @@ func setupNode(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, reg return nil } -func setupTrigger(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, registry *registry.Registry, node *models.CanvasNode, webhookBaseURL string) error { +func setupTrigger(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, registry *registry.Registry, node *models.CanvasNode, webhookBaseURL string, organizationID uuid.UUID) error { ref := node.Ref.Data() trigger, err := registry.GetTrigger(ref.Trigger.Name) if err != nil { @@ -336,6 +336,7 @@ func setupTrigger(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, Requests: contexts.NewNodeRequestContext(tx, node), Events: contexts.NewEventContext(tx, node), Webhook: contexts.NewNodeWebhookContext(ctx, tx, encryptor, node, webhookBaseURL), + Secrets: contexts.NewSecretsContext(tx, organizationID, encryptor), } if node.AppInstallationID != nil { @@ -363,7 +364,7 @@ func setupTrigger(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, return tx.Save(node).Error } -func setupComponent(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, registry *registry.Registry, node *models.CanvasNode, webhookBaseURL string) error { +func setupComponent(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor, registry *registry.Registry, node *models.CanvasNode, webhookBaseURL string, organizationID uuid.UUID) error { ref := node.Ref.Data() component, err := registry.GetComponent(ref.Component.Name) if err != nil { @@ -377,6 +378,7 @@ func setupComponent(ctx context.Context, tx *gorm.DB, encryptor crypto.Encryptor Metadata: contexts.NewNodeMetadataContext(tx, node), Requests: contexts.NewNodeRequestContext(tx, node), Webhook: contexts.NewNodeWebhookContext(ctx, tx, encryptor, node, webhookBaseURL), + Secrets: contexts.NewSecretsContext(tx, organizationID, encryptor), } if node.AppInstallationID != nil { diff --git a/pkg/grpc/actions/common.go b/pkg/grpc/actions/common.go index 79c780b356..c5c6864a22 100644 --- a/pkg/grpc/actions/common.go +++ b/pkg/grpc/actions/common.go @@ -1128,6 +1128,11 @@ func SerializeComponents(in []core.Component) []*componentpb.Component { } exampleOutput, _ := structpb.NewStruct(component.ExampleOutput()) + source := "" + if sp, ok := component.(interface{ Source() string }); ok { + source = sp.Source() + } + out[i] = &componentpb.Component{ Name: component.Name(), Label: component.Label(), @@ -1137,6 +1142,7 @@ func SerializeComponents(in []core.Component) []*componentpb.Component { OutputChannels: channels, Configuration: configuration, ExampleOutput: exampleOutput, + Source: source, } } @@ -1154,6 +1160,11 @@ func SerializeTriggers(in []core.Trigger) []*triggerpb.Trigger { } exampleData, _ := structpb.NewStruct(trigger.ExampleData()) + source := "" + if sp, ok := trigger.(interface{ Source() string }); ok { + source = sp.Source() + } + out[i] = &triggerpb.Trigger{ Name: trigger.Name(), Label: trigger.Label(), @@ -1162,6 +1173,7 @@ func SerializeTriggers(in []core.Trigger) []*triggerpb.Trigger { Color: trigger.Color(), Configuration: configuration, ExampleData: exampleData, + Source: source, } } return out diff --git a/pkg/grpc/actions/scripts/common.go b/pkg/grpc/actions/scripts/common.go new file mode 100644 index 0000000000..5ac84f4bb3 --- /dev/null +++ b/pkg/grpc/actions/scripts/common.go @@ -0,0 +1,34 @@ +package scripts + +import ( + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func SerializeScript(in *models.Script) *pb.Script { + s := &pb.Script{ + Id: in.ID.String(), + OrganizationId: in.OrganizationID.String(), + Name: in.Name, + Label: in.Label, + Description: in.Description, + Source: in.Source, + ManifestJson: string(in.Manifest), + Status: in.Status, + } + + if in.CreatedBy != nil { + s.CreatedBy = in.CreatedBy.String() + } + + if in.CreatedAt != nil { + s.CreatedAt = timestamppb.New(*in.CreatedAt) + } + + if in.UpdatedAt != nil { + s.UpdatedAt = timestamppb.New(*in.UpdatedAt) + } + + return s +} diff --git a/pkg/grpc/actions/scripts/create_script.go b/pkg/grpc/actions/scripts/create_script.go new file mode 100644 index 0000000000..0d3bda5613 --- /dev/null +++ b/pkg/grpc/actions/scripts/create_script.go @@ -0,0 +1,67 @@ +package scripts + +import ( + "context" + "strings" + "time" + + "github.com/google/uuid" + "github.com/superplanehq/superplane/pkg/authentication" + "github.com/superplanehq/superplane/pkg/database" + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gorm.io/datatypes" +) + +func CreateScript(ctx context.Context, organizationID string, script *pb.Script) (*pb.CreateScriptResponse, error) { + if script.Name == "" { + return nil, status.Error(codes.InvalidArgument, "script name is required") + } + + userID, ok := authentication.GetUserIdFromMetadata(ctx) + if !ok { + return nil, status.Error(codes.Unauthenticated, "user not authenticated") + } + + createdBy := uuid.MustParse(userID) + orgID := uuid.MustParse(organizationID) + now := time.Now() + + manifest := datatypes.JSON([]byte("{}")) + if script.ManifestJson != "" { + manifest = datatypes.JSON([]byte(script.ManifestJson)) + } + + scriptStatus := models.ScriptStatusDraft + if script.Status != "" { + scriptStatus = script.Status + } + + model := &models.Script{ + ID: uuid.New(), + OrganizationID: orgID, + Name: script.Name, + Label: script.Label, + Description: script.Description, + Source: script.Source, + Manifest: manifest, + Status: scriptStatus, + CreatedBy: &createdBy, + CreatedAt: &now, + UpdatedAt: &now, + } + + err := database.Conn().Create(model).Error + if err != nil { + if strings.Contains(err.Error(), "unique constraint") { + return nil, status.Error(codes.InvalidArgument, "a script with this name already exists in this organization") + } + return nil, err + } + + return &pb.CreateScriptResponse{ + Script: SerializeScript(model), + }, nil +} diff --git a/pkg/grpc/actions/scripts/delete_script.go b/pkg/grpc/actions/scripts/delete_script.go new file mode 100644 index 0000000000..23a121139f --- /dev/null +++ b/pkg/grpc/actions/scripts/delete_script.go @@ -0,0 +1,29 @@ +package scripts + +import ( + "context" + + "github.com/google/uuid" + "github.com/superplanehq/superplane/pkg/database" + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func DeleteScript(ctx context.Context, organizationID string, id string) (*pb.DeleteScriptResponse, error) { + if _, err := uuid.Parse(id); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid script id: %v", err) + } + + script, err := models.FindScript(organizationID, id) + if err != nil { + return nil, status.Errorf(codes.NotFound, "script not found") + } + + if err := database.Conn().Delete(script).Error; err != nil { + return nil, err + } + + return &pb.DeleteScriptResponse{}, nil +} diff --git a/pkg/grpc/actions/scripts/describe_script.go b/pkg/grpc/actions/scripts/describe_script.go new file mode 100644 index 0000000000..e5dc05ef7a --- /dev/null +++ b/pkg/grpc/actions/scripts/describe_script.go @@ -0,0 +1,26 @@ +package scripts + +import ( + "context" + + "github.com/google/uuid" + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func DescribeScript(ctx context.Context, organizationID string, id string) (*pb.DescribeScriptResponse, error) { + if _, err := uuid.Parse(id); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid script id: %v", err) + } + + script, err := models.FindScript(organizationID, id) + if err != nil { + return nil, status.Errorf(codes.NotFound, "script not found") + } + + return &pb.DescribeScriptResponse{ + Script: SerializeScript(script), + }, nil +} diff --git a/pkg/grpc/actions/scripts/generate_script.go b/pkg/grpc/actions/scripts/generate_script.go new file mode 100644 index 0000000000..11d3eed6a3 --- /dev/null +++ b/pkg/grpc/actions/scripts/generate_script.go @@ -0,0 +1,41 @@ +package scripts + +import ( + "context" + + "github.com/google/uuid" + "github.com/superplanehq/superplane/pkg/ai" + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func GenerateScript(ctx context.Context, aiClient *ai.Client, organizationID string, scriptID string, message string) (*pb.GenerateScriptResponse, error) { + if aiClient == nil { + return nil, status.Error(codes.FailedPrecondition, "AI generation is not configured (OPENAI_API_KEY not set)") + } + + if message == "" { + return nil, status.Error(codes.InvalidArgument, "message is required") + } + + if _, err := uuid.Parse(scriptID); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid script id: %v", err) + } + + script, err := models.FindScript(organizationID, scriptID) + if err != nil { + return nil, status.Errorf(codes.NotFound, "script not found") + } + + response, source, err := aiClient.GenerateScript(ctx, message, script.Source) + if err != nil { + return nil, status.Errorf(codes.Internal, "AI generation failed: %v", err) + } + + return &pb.GenerateScriptResponse{ + Response: response, + Source: source, + }, nil +} diff --git a/pkg/grpc/actions/scripts/list_scripts.go b/pkg/grpc/actions/scripts/list_scripts.go new file mode 100644 index 0000000000..ffb1a3123f --- /dev/null +++ b/pkg/grpc/actions/scripts/list_scripts.go @@ -0,0 +1,24 @@ +package scripts + +import ( + "context" + + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" +) + +func ListScripts(ctx context.Context, organizationID string) (*pb.ListScriptsResponse, error) { + scripts, err := models.FindScriptsByOrganization(organizationID) + if err != nil { + return nil, err + } + + protoScripts := make([]*pb.Script, len(scripts)) + for i, s := range scripts { + protoScripts[i] = SerializeScript(&s) + } + + return &pb.ListScriptsResponse{ + Scripts: protoScripts, + }, nil +} diff --git a/pkg/grpc/actions/scripts/update_script.go b/pkg/grpc/actions/scripts/update_script.go new file mode 100644 index 0000000000..4c117c1670 --- /dev/null +++ b/pkg/grpc/actions/scripts/update_script.go @@ -0,0 +1,61 @@ +package scripts + +import ( + "context" + "time" + + "github.com/google/uuid" + "github.com/superplanehq/superplane/pkg/database" + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gorm.io/datatypes" +) + +func UpdateScript(ctx context.Context, organizationID string, id string, script *pb.Script) (*pb.UpdateScriptResponse, error) { + if _, err := uuid.Parse(id); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid script id: %v", err) + } + + existing, err := models.FindScript(organizationID, id) + if err != nil { + return nil, status.Errorf(codes.NotFound, "script not found") + } + + now := time.Now() + existing.UpdatedAt = &now + + if script.Name != "" { + existing.Name = script.Name + } + + if script.Label != "" { + existing.Label = script.Label + } + + if script.Description != "" { + existing.Description = script.Description + } + + if script.Source != "" { + existing.Source = script.Source + } + + if script.ManifestJson != "" { + existing.Manifest = datatypes.JSON([]byte(script.ManifestJson)) + } + + if script.Status != "" { + existing.Status = script.Status + } + + err = database.Conn().Save(existing).Error + if err != nil { + return nil, err + } + + return &pb.UpdateScriptResponse{ + Script: SerializeScript(existing), + }, nil +} diff --git a/pkg/grpc/scripts_service.go b/pkg/grpc/scripts_service.go new file mode 100644 index 0000000000..2d0f7d2153 --- /dev/null +++ b/pkg/grpc/scripts_service.go @@ -0,0 +1,113 @@ +package grpc + +import ( + "context" + + log "github.com/sirupsen/logrus" + "github.com/superplanehq/superplane/pkg/ai" + "github.com/superplanehq/superplane/pkg/authorization" + scripts "github.com/superplanehq/superplane/pkg/grpc/actions/scripts" + "github.com/superplanehq/superplane/pkg/models" + pb "github.com/superplanehq/superplane/pkg/protos/scripts" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type PluginActivator interface { + ActivateScript(name string, source string, manifestJSON []byte) error + DeactivateScript(name string) error +} + +type ScriptsService struct { + pb.UnimplementedScriptsServer + aiClient *ai.Client + pluginManager PluginActivator +} + +func NewScriptsService(aiClient *ai.Client, pluginManager PluginActivator) *ScriptsService { + return &ScriptsService{aiClient: aiClient, pluginManager: pluginManager} +} + +func (s *ScriptsService) ListScripts(ctx context.Context, req *pb.ListScriptsRequest) (*pb.ListScriptsResponse, error) { + organizationID := ctx.Value(authorization.OrganizationContextKey).(string) + return scripts.ListScripts(ctx, organizationID) +} + +func (s *ScriptsService) DescribeScript(ctx context.Context, req *pb.DescribeScriptRequest) (*pb.DescribeScriptResponse, error) { + organizationID := ctx.Value(authorization.OrganizationContextKey).(string) + return scripts.DescribeScript(ctx, organizationID, req.Id) +} + +func (s *ScriptsService) CreateScript(ctx context.Context, req *pb.CreateScriptRequest) (*pb.CreateScriptResponse, error) { + if req.Script == nil { + return nil, status.Error(codes.InvalidArgument, "script is required") + } + organizationID := ctx.Value(authorization.OrganizationContextKey).(string) + return scripts.CreateScript(ctx, organizationID, req.Script) +} + +func (s *ScriptsService) UpdateScript(ctx context.Context, req *pb.UpdateScriptRequest) (*pb.UpdateScriptResponse, error) { + if req.Script == nil { + return nil, status.Error(codes.InvalidArgument, "script is required") + } + organizationID := ctx.Value(authorization.OrganizationContextKey).(string) + resp, err := scripts.UpdateScript(ctx, organizationID, req.Id, req.Script) + if err != nil { + return nil, err + } + + if s.pluginManager != nil && req.Script.Status != "" { + s.handleScriptStatusChange(resp.Script) + } + + return resp, nil +} + +func (s *ScriptsService) handleScriptStatusChange(script *pb.Script) { + if script == nil { + log.Warn("handleScriptStatusChange: script is nil") + return + } + + log.Infof("handleScriptStatusChange: name=%s, status=%s, sourceLen=%d, pluginManager=%v", + script.Name, script.Status, len(script.Source), s.pluginManager != nil) + + switch script.Status { + case models.ScriptStatusActive: + manifest := []byte(script.ManifestJson) + if len(manifest) == 0 { + manifest = []byte("{}") + } + if err := s.pluginManager.ActivateScript(script.Name, script.Source, manifest); err != nil { + log.WithError(err).Errorf("Failed to activate script %s", script.Name) + } else { + log.Infof("Script %s activated via API", script.Name) + } + case models.ScriptStatusDraft: + if err := s.pluginManager.DeactivateScript(script.Name); err != nil { + log.WithError(err).Errorf("Failed to deactivate script %s", script.Name) + } + default: + log.Infof("handleScriptStatusChange: unhandled status %s for script %s", script.Status, script.Name) + } +} + +func (s *ScriptsService) DeleteScript(ctx context.Context, req *pb.DeleteScriptRequest) (*pb.DeleteScriptResponse, error) { + organizationID := ctx.Value(authorization.OrganizationContextKey).(string) + + if s.pluginManager != nil { + existing, err := models.FindScript(organizationID, req.Id) + if err == nil && existing.Status == models.ScriptStatusActive { + if err := s.pluginManager.DeactivateScript(existing.Name); err != nil { + log.WithError(err).Errorf("Failed to deactivate script %s before deletion", existing.Name) + } + } + } + + return scripts.DeleteScript(ctx, organizationID, req.Id) +} + +func (s *ScriptsService) GenerateScript(ctx context.Context, req *pb.GenerateScriptRequest) (*pb.GenerateScriptResponse, error) { + organizationID := ctx.Value(authorization.OrganizationContextKey).(string) + return scripts.GenerateScript(ctx, s.aiClient, organizationID, req.ScriptId, req.Message) +} diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go index c4ed18afef..5f0883e75b 100644 --- a/pkg/grpc/server.go +++ b/pkg/grpc/server.go @@ -10,6 +10,7 @@ import ( log "github.com/sirupsen/logrus" recovery "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" + "github.com/superplanehq/superplane/pkg/ai" "github.com/superplanehq/superplane/pkg/authorization" "github.com/superplanehq/superplane/pkg/crypto" "github.com/superplanehq/superplane/pkg/oidc" @@ -21,6 +22,7 @@ import ( mepb "github.com/superplanehq/superplane/pkg/protos/me" organizationPb "github.com/superplanehq/superplane/pkg/protos/organizations" pbRoles "github.com/superplanehq/superplane/pkg/protos/roles" + pbScripts "github.com/superplanehq/superplane/pkg/protos/scripts" secretPb "github.com/superplanehq/superplane/pkg/protos/secrets" pbServiceAccounts "github.com/superplanehq/superplane/pkg/protos/service_accounts" triggerPb "github.com/superplanehq/superplane/pkg/protos/triggers" @@ -54,7 +56,7 @@ func sentryRecoveryHandler(p any) error { return status.Errorf(codes.Internal, "internal server error") } -func RunServer(baseURL, webhooksBaseURL, basePath string, encryptor crypto.Encryptor, authService authorization.Authorization, registry *registry.Registry, oidcProvider oidc.Provider, port int) { +func RunServer(baseURL, webhooksBaseURL, basePath string, encryptor crypto.Encryptor, authService authorization.Authorization, registry *registry.Registry, oidcProvider oidc.Provider, aiClient *ai.Client, pluginManager PluginActivator, port int) { endpoint := fmt.Sprintf("0.0.0.0:%d", port) lis, err := net.Listen("tcp", endpoint) @@ -128,6 +130,9 @@ func RunServer(baseURL, webhooksBaseURL, basePath string, encryptor crypto.Encry serviceAccountsService := NewServiceAccountsService(authService) pbServiceAccounts.RegisterServiceAccountsServer(grpcServer, serviceAccountsService) + scriptsService := NewScriptsService(aiClient, pluginManager) + pbScripts.RegisterScriptsServer(grpcServer, scriptsService) + reflection.Register(grpcServer) // diff --git a/pkg/models/script.go b/pkg/models/script.go new file mode 100644 index 0000000000..de5b5fd8e1 --- /dev/null +++ b/pkg/models/script.go @@ -0,0 +1,105 @@ +package models + +import ( + "time" + + "github.com/google/uuid" + "github.com/superplanehq/superplane/pkg/database" + "gorm.io/datatypes" + "gorm.io/gorm" +) + +type Script struct { + ID uuid.UUID + OrganizationID uuid.UUID + Name string + Label string + Description string + Source string + Manifest datatypes.JSON + Status string + CreatedBy *uuid.UUID + CreatedAt *time.Time + UpdatedAt *time.Time +} + +const ( + ScriptStatusDraft = "draft" + ScriptStatusActive = "active" + ScriptStatusError = "error" +) + +func FindScript(orgID, id string) (*Script, error) { + return FindScriptInTransaction(database.Conn(), orgID, id) +} + +func FindScriptInTransaction(tx *gorm.DB, orgID, id string) (*Script, error) { + var script Script + err := tx. + Where("organization_id = ?", orgID). + Where("id = ?", id). + First(&script). + Error + + if err != nil { + return nil, err + } + + return &script, nil +} + +func FindScriptsByOrganization(orgID string) ([]Script, error) { + return FindScriptsByOrganizationInTransaction(database.Conn(), orgID) +} + +func FindScriptsByOrganizationInTransaction(tx *gorm.DB, orgID string) ([]Script, error) { + var scripts []Script + err := tx. + Where("organization_id = ?", orgID). + Order("created_at DESC"). + Find(&scripts). + Error + + if err != nil { + return nil, err + } + + return scripts, nil +} + +func FindActiveScripts() ([]Script, error) { + return FindActiveScriptsInTransaction(database.Conn()) +} + +func FindActiveScriptsInTransaction(tx *gorm.DB) ([]Script, error) { + var scripts []Script + err := tx. + Where("status = ?", ScriptStatusActive). + Find(&scripts). + Error + + if err != nil { + return nil, err + } + + return scripts, nil +} + +func FindScriptByName(orgID uuid.UUID, name string) (*Script, error) { + return FindScriptByNameInTransaction(database.Conn(), orgID, name) +} + +func FindScriptByNameInTransaction(tx *gorm.DB, orgID uuid.UUID, name string) (*Script, error) { + var script Script + err := tx. + Where("organization_id = ?", orgID). + Where("name = ?", name). + First(&script). + Error + + if err != nil { + return nil, err + } + + return &script, nil +} diff --git a/pkg/openapi_client/.openapi-generator/FILES b/pkg/openapi_client/.openapi-generator/FILES index a34eb5ca84..70bffa26cf 100644 --- a/pkg/openapi_client/.openapi-generator/FILES +++ b/pkg/openapi_client/.openapi-generator/FILES @@ -14,6 +14,7 @@ api_integration.go api_me.go api_organization.go api_roles.go +api_script.go api_secret.go api_service_accounts.go api_trigger.go @@ -163,6 +164,16 @@ docs/RolesRoleMetadata.md docs/RolesRoleSpec.md docs/RolesUpdateRoleBody.md docs/RolesUpdateRoleResponse.md +docs/ScriptAPI.md +docs/ScriptsCreateScriptRequest.md +docs/ScriptsCreateScriptResponse.md +docs/ScriptsDescribeScriptResponse.md +docs/ScriptsGenerateScriptBody.md +docs/ScriptsGenerateScriptResponse.md +docs/ScriptsListScriptsResponse.md +docs/ScriptsScript.md +docs/ScriptsUpdateScriptBody.md +docs/ScriptsUpdateScriptResponse.md docs/SecretAPI.md docs/SecretLocal.md docs/SecretProvider.md @@ -346,6 +357,15 @@ model_roles_role_metadata.go model_roles_role_spec.go model_roles_update_role_body.go model_roles_update_role_response.go +model_scripts_create_script_request.go +model_scripts_create_script_response.go +model_scripts_describe_script_response.go +model_scripts_generate_script_body.go +model_scripts_generate_script_response.go +model_scripts_list_scripts_response.go +model_scripts_script.go +model_scripts_update_script_body.go +model_scripts_update_script_response.go model_secret_local.go model_secret_provider.go model_secrets_create_secret_request.go @@ -404,6 +424,7 @@ test/api_integration_test.go test/api_me_test.go test/api_organization_test.go test/api_roles_test.go +test/api_script_test.go test/api_secret_test.go test/api_service_accounts_test.go test/api_trigger_test.go diff --git a/pkg/openapi_client/api_blueprint.go b/pkg/openapi_client/api_blueprint.go index 64d92caad9..232a33ed9f 100644 --- a/pkg/openapi_client/api_blueprint.go +++ b/pkg/openapi_client/api_blueprint.go @@ -20,13 +20,14 @@ import ( "strings" ) + // BlueprintAPIService BlueprintAPI service type BlueprintAPIService service type ApiBlueprintsCreateBlueprintRequest struct { - ctx context.Context + ctx context.Context ApiService *BlueprintAPIService - body *BlueprintsCreateBlueprintRequest + body *BlueprintsCreateBlueprintRequest } func (r ApiBlueprintsCreateBlueprintRequest) Body(body BlueprintsCreateBlueprintRequest) ApiBlueprintsCreateBlueprintRequest { @@ -43,25 +44,24 @@ BlueprintsCreateBlueprint Create blueprint Creates a new blueprint - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiBlueprintsCreateBlueprintRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiBlueprintsCreateBlueprintRequest */ func (a *BlueprintAPIService) BlueprintsCreateBlueprint(ctx context.Context) ApiBlueprintsCreateBlueprintRequest { return ApiBlueprintsCreateBlueprintRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return BlueprintsCreateBlueprintResponse +// @return BlueprintsCreateBlueprintResponse func (a *BlueprintAPIService) BlueprintsCreateBlueprintExecute(r ApiBlueprintsCreateBlueprintRequest) (*BlueprintsCreateBlueprintResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *BlueprintsCreateBlueprintResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *BlueprintsCreateBlueprintResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlueprintAPIService.BlueprintsCreateBlueprint") @@ -119,14 +119,14 @@ func (a *BlueprintAPIService) BlueprintsCreateBlueprintExecute(r ApiBlueprintsCr body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -143,9 +143,9 @@ func (a *BlueprintAPIService) BlueprintsCreateBlueprintExecute(r ApiBlueprintsCr } type ApiBlueprintsDeleteBlueprintRequest struct { - ctx context.Context + ctx context.Context ApiService *BlueprintAPIService - id string + id string } func (r ApiBlueprintsDeleteBlueprintRequest) Execute() (map[string]interface{}, *http.Response, error) { @@ -157,27 +157,26 @@ BlueprintsDeleteBlueprint Delete blueprint Deletes an existing blueprint - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiBlueprintsDeleteBlueprintRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiBlueprintsDeleteBlueprintRequest */ func (a *BlueprintAPIService) BlueprintsDeleteBlueprint(ctx context.Context, id string) ApiBlueprintsDeleteBlueprintRequest { return ApiBlueprintsDeleteBlueprintRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *BlueprintAPIService) BlueprintsDeleteBlueprintExecute(r ApiBlueprintsDeleteBlueprintRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlueprintAPIService.BlueprintsDeleteBlueprint") @@ -231,14 +230,14 @@ func (a *BlueprintAPIService) BlueprintsDeleteBlueprintExecute(r ApiBlueprintsDe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -255,9 +254,9 @@ func (a *BlueprintAPIService) BlueprintsDeleteBlueprintExecute(r ApiBlueprintsDe } type ApiBlueprintsDescribeBlueprintRequest struct { - ctx context.Context + ctx context.Context ApiService *BlueprintAPIService - id string + id string } func (r ApiBlueprintsDescribeBlueprintRequest) Execute() (*BlueprintsDescribeBlueprintResponse, *http.Response, error) { @@ -269,27 +268,26 @@ BlueprintsDescribeBlueprint Describe blueprint Returns a blueprint - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiBlueprintsDescribeBlueprintRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiBlueprintsDescribeBlueprintRequest */ func (a *BlueprintAPIService) BlueprintsDescribeBlueprint(ctx context.Context, id string) ApiBlueprintsDescribeBlueprintRequest { return ApiBlueprintsDescribeBlueprintRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return BlueprintsDescribeBlueprintResponse +// @return BlueprintsDescribeBlueprintResponse func (a *BlueprintAPIService) BlueprintsDescribeBlueprintExecute(r ApiBlueprintsDescribeBlueprintRequest) (*BlueprintsDescribeBlueprintResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *BlueprintsDescribeBlueprintResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *BlueprintsDescribeBlueprintResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlueprintAPIService.BlueprintsDescribeBlueprint") @@ -343,14 +341,14 @@ func (a *BlueprintAPIService) BlueprintsDescribeBlueprintExecute(r ApiBlueprints body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -367,7 +365,7 @@ func (a *BlueprintAPIService) BlueprintsDescribeBlueprintExecute(r ApiBlueprints } type ApiBlueprintsListBlueprintsRequest struct { - ctx context.Context + ctx context.Context ApiService *BlueprintAPIService } @@ -380,25 +378,24 @@ BlueprintsListBlueprints List blueprints Returns a list of all blueprints - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiBlueprintsListBlueprintsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiBlueprintsListBlueprintsRequest */ func (a *BlueprintAPIService) BlueprintsListBlueprints(ctx context.Context) ApiBlueprintsListBlueprintsRequest { return ApiBlueprintsListBlueprintsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return BlueprintsListBlueprintsResponse +// @return BlueprintsListBlueprintsResponse func (a *BlueprintAPIService) BlueprintsListBlueprintsExecute(r ApiBlueprintsListBlueprintsRequest) (*BlueprintsListBlueprintsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *BlueprintsListBlueprintsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *BlueprintsListBlueprintsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlueprintAPIService.BlueprintsListBlueprints") @@ -451,14 +448,14 @@ func (a *BlueprintAPIService) BlueprintsListBlueprintsExecute(r ApiBlueprintsLis body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -475,10 +472,10 @@ func (a *BlueprintAPIService) BlueprintsListBlueprintsExecute(r ApiBlueprintsLis } type ApiBlueprintsUpdateBlueprintRequest struct { - ctx context.Context + ctx context.Context ApiService *BlueprintAPIService - id string - body *BlueprintsUpdateBlueprintBody + id string + body *BlueprintsUpdateBlueprintBody } func (r ApiBlueprintsUpdateBlueprintRequest) Body(body BlueprintsUpdateBlueprintBody) ApiBlueprintsUpdateBlueprintRequest { @@ -495,27 +492,26 @@ BlueprintsUpdateBlueprint Update blueprint Updates an existing blueprint - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiBlueprintsUpdateBlueprintRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiBlueprintsUpdateBlueprintRequest */ func (a *BlueprintAPIService) BlueprintsUpdateBlueprint(ctx context.Context, id string) ApiBlueprintsUpdateBlueprintRequest { return ApiBlueprintsUpdateBlueprintRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return BlueprintsUpdateBlueprintResponse +// @return BlueprintsUpdateBlueprintResponse func (a *BlueprintAPIService) BlueprintsUpdateBlueprintExecute(r ApiBlueprintsUpdateBlueprintRequest) (*BlueprintsUpdateBlueprintResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *BlueprintsUpdateBlueprintResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *BlueprintsUpdateBlueprintResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlueprintAPIService.BlueprintsUpdateBlueprint") @@ -574,14 +570,14 @@ func (a *BlueprintAPIService) BlueprintsUpdateBlueprintExecute(r ApiBlueprintsUp body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_canvas.go b/pkg/openapi_client/api_canvas.go index 86225c77b5..a6f433b2c1 100644 --- a/pkg/openapi_client/api_canvas.go +++ b/pkg/openapi_client/api_canvas.go @@ -20,13 +20,14 @@ import ( "strings" ) + // CanvasAPIService CanvasAPI service type CanvasAPIService service type ApiCanvasesCreateCanvasRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasAPIService - body *CanvasesCreateCanvasRequest + body *CanvasesCreateCanvasRequest } func (r ApiCanvasesCreateCanvasRequest) Body(body CanvasesCreateCanvasRequest) ApiCanvasesCreateCanvasRequest { @@ -43,25 +44,24 @@ CanvasesCreateCanvas Create canvas Creates a new canvas - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiCanvasesCreateCanvasRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCanvasesCreateCanvasRequest */ func (a *CanvasAPIService) CanvasesCreateCanvas(ctx context.Context) ApiCanvasesCreateCanvasRequest { return ApiCanvasesCreateCanvasRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return CanvasesCreateCanvasResponse +// @return CanvasesCreateCanvasResponse func (a *CanvasAPIService) CanvasesCreateCanvasExecute(r ApiCanvasesCreateCanvasRequest) (*CanvasesCreateCanvasResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesCreateCanvasResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesCreateCanvasResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasAPIService.CanvasesCreateCanvas") @@ -119,14 +119,14 @@ func (a *CanvasAPIService) CanvasesCreateCanvasExecute(r ApiCanvasesCreateCanvas body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -143,9 +143,9 @@ func (a *CanvasAPIService) CanvasesCreateCanvasExecute(r ApiCanvasesCreateCanvas } type ApiCanvasesDeleteCanvasRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasAPIService - id string + id string } func (r ApiCanvasesDeleteCanvasRequest) Execute() (map[string]interface{}, *http.Response, error) { @@ -157,27 +157,26 @@ CanvasesDeleteCanvas Delete canvas Deletes an existing canvas - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiCanvasesDeleteCanvasRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiCanvasesDeleteCanvasRequest */ func (a *CanvasAPIService) CanvasesDeleteCanvas(ctx context.Context, id string) ApiCanvasesDeleteCanvasRequest { return ApiCanvasesDeleteCanvasRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *CanvasAPIService) CanvasesDeleteCanvasExecute(r ApiCanvasesDeleteCanvasRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasAPIService.CanvasesDeleteCanvas") @@ -231,14 +230,14 @@ func (a *CanvasAPIService) CanvasesDeleteCanvasExecute(r ApiCanvasesDeleteCanvas body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -255,9 +254,9 @@ func (a *CanvasAPIService) CanvasesDeleteCanvasExecute(r ApiCanvasesDeleteCanvas } type ApiCanvasesDescribeCanvasRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasAPIService - id string + id string } func (r ApiCanvasesDescribeCanvasRequest) Execute() (*CanvasesDescribeCanvasResponse, *http.Response, error) { @@ -269,27 +268,26 @@ CanvasesDescribeCanvas Describe canvas Returns a canvas by ID - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiCanvasesDescribeCanvasRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiCanvasesDescribeCanvasRequest */ func (a *CanvasAPIService) CanvasesDescribeCanvas(ctx context.Context, id string) ApiCanvasesDescribeCanvasRequest { return ApiCanvasesDescribeCanvasRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return CanvasesDescribeCanvasResponse +// @return CanvasesDescribeCanvasResponse func (a *CanvasAPIService) CanvasesDescribeCanvasExecute(r ApiCanvasesDescribeCanvasRequest) (*CanvasesDescribeCanvasResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesDescribeCanvasResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesDescribeCanvasResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasAPIService.CanvasesDescribeCanvas") @@ -343,14 +341,14 @@ func (a *CanvasAPIService) CanvasesDescribeCanvasExecute(r ApiCanvasesDescribeCa body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -367,8 +365,8 @@ func (a *CanvasAPIService) CanvasesDescribeCanvasExecute(r ApiCanvasesDescribeCa } type ApiCanvasesListCanvasesRequest struct { - ctx context.Context - ApiService *CanvasAPIService + ctx context.Context + ApiService *CanvasAPIService includeTemplates *bool } @@ -386,25 +384,24 @@ CanvasesListCanvases List canvases Returns a list of all canvases - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiCanvasesListCanvasesRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCanvasesListCanvasesRequest */ func (a *CanvasAPIService) CanvasesListCanvases(ctx context.Context) ApiCanvasesListCanvasesRequest { return ApiCanvasesListCanvasesRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return CanvasesListCanvasesResponse +// @return CanvasesListCanvasesResponse func (a *CanvasAPIService) CanvasesListCanvasesExecute(r ApiCanvasesListCanvasesRequest) (*CanvasesListCanvasesResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListCanvasesResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListCanvasesResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasAPIService.CanvasesListCanvases") @@ -460,14 +457,14 @@ func (a *CanvasAPIService) CanvasesListCanvasesExecute(r ApiCanvasesListCanvases body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -484,10 +481,10 @@ func (a *CanvasAPIService) CanvasesListCanvasesExecute(r ApiCanvasesListCanvases } type ApiCanvasesUpdateCanvasRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasAPIService - id string - body *CanvasesUpdateCanvasBody + id string + body *CanvasesUpdateCanvasBody } func (r ApiCanvasesUpdateCanvasRequest) Body(body CanvasesUpdateCanvasBody) ApiCanvasesUpdateCanvasRequest { @@ -504,27 +501,26 @@ CanvasesUpdateCanvas Update canvas Updates an existing canvas - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiCanvasesUpdateCanvasRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiCanvasesUpdateCanvasRequest */ func (a *CanvasAPIService) CanvasesUpdateCanvas(ctx context.Context, id string) ApiCanvasesUpdateCanvasRequest { return ApiCanvasesUpdateCanvasRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return CanvasesUpdateCanvasResponse +// @return CanvasesUpdateCanvasResponse func (a *CanvasAPIService) CanvasesUpdateCanvasExecute(r ApiCanvasesUpdateCanvasRequest) (*CanvasesUpdateCanvasResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesUpdateCanvasResponse + localVarHTTPMethod = http.MethodPut + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesUpdateCanvasResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasAPIService.CanvasesUpdateCanvas") @@ -583,14 +579,14 @@ func (a *CanvasAPIService) CanvasesUpdateCanvasExecute(r ApiCanvasesUpdateCanvas body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_canvas_event.go b/pkg/openapi_client/api_canvas_event.go index 9734f11739..bccccb3a7c 100644 --- a/pkg/openapi_client/api_canvas_event.go +++ b/pkg/openapi_client/api_canvas_event.go @@ -21,15 +21,16 @@ import ( "time" ) + // CanvasEventAPIService CanvasEventAPI service type CanvasEventAPIService service type ApiCanvasesListCanvasEventsRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasEventAPIService - canvasId string - limit *int64 - before *time.Time + canvasId string + limit *int64 + before *time.Time } func (r ApiCanvasesListCanvasEventsRequest) Limit(limit int64) ApiCanvasesListCanvasEventsRequest { @@ -51,27 +52,26 @@ CanvasesListCanvasEvents List canvas events Returns a list of root events that triggered executions in a canvas - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @return ApiCanvasesListCanvasEventsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @return ApiCanvasesListCanvasEventsRequest */ func (a *CanvasEventAPIService) CanvasesListCanvasEvents(ctx context.Context, canvasId string) ApiCanvasesListCanvasEventsRequest { return ApiCanvasesListCanvasEventsRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, + ctx: ctx, + canvasId: canvasId, } } // Execute executes the request -// -// @return CanvasesListCanvasEventsResponse +// @return CanvasesListCanvasEventsResponse func (a *CanvasEventAPIService) CanvasesListCanvasEventsExecute(r ApiCanvasesListCanvasEventsRequest) (*CanvasesListCanvasEventsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListCanvasEventsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListCanvasEventsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasEventAPIService.CanvasesListCanvasEvents") @@ -131,14 +131,14 @@ func (a *CanvasEventAPIService) CanvasesListCanvasEventsExecute(r ApiCanvasesLis body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -155,10 +155,10 @@ func (a *CanvasEventAPIService) CanvasesListCanvasEventsExecute(r ApiCanvasesLis } type ApiCanvasesListEventExecutionsRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasEventAPIService - canvasId string - eventId string + canvasId string + eventId string } func (r ApiCanvasesListEventExecutionsRequest) Execute() (*CanvasesListEventExecutionsResponse, *http.Response, error) { @@ -170,29 +170,28 @@ CanvasesListEventExecutions List event executions Returns a list of all node executions triggered by a root event - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param eventId - @return ApiCanvasesListEventExecutionsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param eventId + @return ApiCanvasesListEventExecutionsRequest */ func (a *CanvasEventAPIService) CanvasesListEventExecutions(ctx context.Context, canvasId string, eventId string) ApiCanvasesListEventExecutionsRequest { return ApiCanvasesListEventExecutionsRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - eventId: eventId, + ctx: ctx, + canvasId: canvasId, + eventId: eventId, } } // Execute executes the request -// -// @return CanvasesListEventExecutionsResponse +// @return CanvasesListEventExecutionsResponse func (a *CanvasEventAPIService) CanvasesListEventExecutionsExecute(r ApiCanvasesListEventExecutionsRequest) (*CanvasesListEventExecutionsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListEventExecutionsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListEventExecutionsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasEventAPIService.CanvasesListEventExecutions") @@ -247,14 +246,14 @@ func (a *CanvasEventAPIService) CanvasesListEventExecutionsExecute(r ApiCanvases body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_canvas_node.go b/pkg/openapi_client/api_canvas_node.go index 5edc160c30..2eb7e1534c 100644 --- a/pkg/openapi_client/api_canvas_node.go +++ b/pkg/openapi_client/api_canvas_node.go @@ -17,20 +17,21 @@ import ( "io" "net/http" "net/url" - "reflect" "strings" "time" + "reflect" ) + // CanvasNodeAPIService CanvasNodeAPI service type CanvasNodeAPIService service type ApiCanvasesDeleteNodeQueueItemRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string - itemId string + canvasId string + nodeId string + itemId string } func (r ApiCanvasesDeleteNodeQueueItemRequest) Execute() (map[string]interface{}, *http.Response, error) { @@ -42,31 +43,30 @@ CanvasesDeleteNodeQueueItem Delete item from a node's queue Deletes a specific item in a node's queue - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @param itemId - @return ApiCanvasesDeleteNodeQueueItemRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @param itemId + @return ApiCanvasesDeleteNodeQueueItemRequest */ func (a *CanvasNodeAPIService) CanvasesDeleteNodeQueueItem(ctx context.Context, canvasId string, nodeId string, itemId string) ApiCanvasesDeleteNodeQueueItemRequest { return ApiCanvasesDeleteNodeQueueItemRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, - itemId: itemId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, + itemId: itemId, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *CanvasNodeAPIService) CanvasesDeleteNodeQueueItemExecute(r ApiCanvasesDeleteNodeQueueItemRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesDeleteNodeQueueItem") @@ -122,14 +122,14 @@ func (a *CanvasNodeAPIService) CanvasesDeleteNodeQueueItemExecute(r ApiCanvasesD body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -146,11 +146,11 @@ func (a *CanvasNodeAPIService) CanvasesDeleteNodeQueueItemExecute(r ApiCanvasesD } type ApiCanvasesEmitNodeEventRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string - body *CanvasesEmitNodeEventBody + canvasId string + nodeId string + body *CanvasesEmitNodeEventBody } func (r ApiCanvasesEmitNodeEventRequest) Body(body CanvasesEmitNodeEventBody) ApiCanvasesEmitNodeEventRequest { @@ -167,29 +167,28 @@ CanvasesEmitNodeEvent Emit output event for canvas node Emit output event for canvas node - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @return ApiCanvasesEmitNodeEventRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @return ApiCanvasesEmitNodeEventRequest */ func (a *CanvasNodeAPIService) CanvasesEmitNodeEvent(ctx context.Context, canvasId string, nodeId string) ApiCanvasesEmitNodeEventRequest { return ApiCanvasesEmitNodeEventRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, } } // Execute executes the request -// -// @return CanvasesEmitNodeEventResponse +// @return CanvasesEmitNodeEventResponse func (a *CanvasNodeAPIService) CanvasesEmitNodeEventExecute(r ApiCanvasesEmitNodeEventRequest) (*CanvasesEmitNodeEventResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesEmitNodeEventResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesEmitNodeEventResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesEmitNodeEvent") @@ -249,14 +248,14 @@ func (a *CanvasNodeAPIService) CanvasesEmitNodeEventExecute(r ApiCanvasesEmitNod body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -273,12 +272,12 @@ func (a *CanvasNodeAPIService) CanvasesEmitNodeEventExecute(r ApiCanvasesEmitNod } type ApiCanvasesInvokeNodeTriggerActionRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string + canvasId string + nodeId string actionName string - body *CanvasesInvokeNodeTriggerActionBody + body *CanvasesInvokeNodeTriggerActionBody } func (r ApiCanvasesInvokeNodeTriggerActionRequest) Body(body CanvasesInvokeNodeTriggerActionBody) ApiCanvasesInvokeNodeTriggerActionRequest { @@ -295,31 +294,30 @@ CanvasesInvokeNodeTriggerAction Invoke trigger action Invokes a custom action on a canvas node trigger - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @param actionName - @return ApiCanvasesInvokeNodeTriggerActionRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @param actionName + @return ApiCanvasesInvokeNodeTriggerActionRequest */ func (a *CanvasNodeAPIService) CanvasesInvokeNodeTriggerAction(ctx context.Context, canvasId string, nodeId string, actionName string) ApiCanvasesInvokeNodeTriggerActionRequest { return ApiCanvasesInvokeNodeTriggerActionRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, actionName: actionName, } } // Execute executes the request -// -// @return CanvasesInvokeNodeTriggerActionResponse +// @return CanvasesInvokeNodeTriggerActionResponse func (a *CanvasNodeAPIService) CanvasesInvokeNodeTriggerActionExecute(r ApiCanvasesInvokeNodeTriggerActionRequest) (*CanvasesInvokeNodeTriggerActionResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesInvokeNodeTriggerActionResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesInvokeNodeTriggerActionResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesInvokeNodeTriggerAction") @@ -380,14 +378,14 @@ func (a *CanvasNodeAPIService) CanvasesInvokeNodeTriggerActionExecute(r ApiCanva body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -404,12 +402,12 @@ func (a *CanvasNodeAPIService) CanvasesInvokeNodeTriggerActionExecute(r ApiCanva } type ApiCanvasesListNodeEventsRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string - limit *int64 - before *time.Time + canvasId string + nodeId string + limit *int64 + before *time.Time } func (r ApiCanvasesListNodeEventsRequest) Limit(limit int64) ApiCanvasesListNodeEventsRequest { @@ -431,29 +429,28 @@ CanvasesListNodeEvents List node events Returns a list of events for a specific canvas node - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @return ApiCanvasesListNodeEventsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @return ApiCanvasesListNodeEventsRequest */ func (a *CanvasNodeAPIService) CanvasesListNodeEvents(ctx context.Context, canvasId string, nodeId string) ApiCanvasesListNodeEventsRequest { return ApiCanvasesListNodeEventsRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, } } // Execute executes the request -// -// @return CanvasesListNodeEventsResponse +// @return CanvasesListNodeEventsResponse func (a *CanvasNodeAPIService) CanvasesListNodeEventsExecute(r ApiCanvasesListNodeEventsRequest) (*CanvasesListNodeEventsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListNodeEventsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListNodeEventsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesListNodeEvents") @@ -514,14 +511,14 @@ func (a *CanvasNodeAPIService) CanvasesListNodeEventsExecute(r ApiCanvasesListNo body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -538,14 +535,14 @@ func (a *CanvasNodeAPIService) CanvasesListNodeEventsExecute(r ApiCanvasesListNo } type ApiCanvasesListNodeExecutionsRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string - states *[]string - results *[]string - limit *int64 - before *time.Time + canvasId string + nodeId string + states *[]string + results *[]string + limit *int64 + before *time.Time } func (r ApiCanvasesListNodeExecutionsRequest) States(states []string) ApiCanvasesListNodeExecutionsRequest { @@ -577,29 +574,28 @@ CanvasesListNodeExecutions List node executions Returns a list of executions for a specific canvas node - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @return ApiCanvasesListNodeExecutionsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @return ApiCanvasesListNodeExecutionsRequest */ func (a *CanvasNodeAPIService) CanvasesListNodeExecutions(ctx context.Context, canvasId string, nodeId string) ApiCanvasesListNodeExecutionsRequest { return ApiCanvasesListNodeExecutionsRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, } } // Execute executes the request -// -// @return CanvasesListNodeExecutionsResponse +// @return CanvasesListNodeExecutionsResponse func (a *CanvasNodeAPIService) CanvasesListNodeExecutionsExecute(r ApiCanvasesListNodeExecutionsRequest) (*CanvasesListNodeExecutionsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListNodeExecutionsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListNodeExecutionsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesListNodeExecutions") @@ -682,14 +678,14 @@ func (a *CanvasNodeAPIService) CanvasesListNodeExecutionsExecute(r ApiCanvasesLi body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -706,12 +702,12 @@ func (a *CanvasNodeAPIService) CanvasesListNodeExecutionsExecute(r ApiCanvasesLi } type ApiCanvasesListNodeQueueItemsRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string - limit *int64 - before *time.Time + canvasId string + nodeId string + limit *int64 + before *time.Time } func (r ApiCanvasesListNodeQueueItemsRequest) Limit(limit int64) ApiCanvasesListNodeQueueItemsRequest { @@ -733,29 +729,28 @@ CanvasesListNodeQueueItems List items in a node's queue Returns a list of items in a node's queue - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @return ApiCanvasesListNodeQueueItemsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @return ApiCanvasesListNodeQueueItemsRequest */ func (a *CanvasNodeAPIService) CanvasesListNodeQueueItems(ctx context.Context, canvasId string, nodeId string) ApiCanvasesListNodeQueueItemsRequest { return ApiCanvasesListNodeQueueItemsRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, } } // Execute executes the request -// -// @return CanvasesListNodeQueueItemsResponse +// @return CanvasesListNodeQueueItemsResponse func (a *CanvasNodeAPIService) CanvasesListNodeQueueItemsExecute(r ApiCanvasesListNodeQueueItemsRequest) (*CanvasesListNodeQueueItemsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListNodeQueueItemsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListNodeQueueItemsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesListNodeQueueItems") @@ -816,14 +811,14 @@ func (a *CanvasNodeAPIService) CanvasesListNodeQueueItemsExecute(r ApiCanvasesLi body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -840,11 +835,11 @@ func (a *CanvasNodeAPIService) CanvasesListNodeQueueItemsExecute(r ApiCanvasesLi } type ApiCanvasesUpdateNodePauseRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeAPIService - canvasId string - nodeId string - body *CanvasesUpdateNodePauseBody + canvasId string + nodeId string + body *CanvasesUpdateNodePauseBody } func (r ApiCanvasesUpdateNodePauseRequest) Body(body CanvasesUpdateNodePauseBody) ApiCanvasesUpdateNodePauseRequest { @@ -861,29 +856,28 @@ CanvasesUpdateNodePause Pause or resume node processing Pauses or resumes processing for a canvas node while continuing to queue incoming items - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param nodeId - @return ApiCanvasesUpdateNodePauseRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param nodeId + @return ApiCanvasesUpdateNodePauseRequest */ func (a *CanvasNodeAPIService) CanvasesUpdateNodePause(ctx context.Context, canvasId string, nodeId string) ApiCanvasesUpdateNodePauseRequest { return ApiCanvasesUpdateNodePauseRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, - nodeId: nodeId, + ctx: ctx, + canvasId: canvasId, + nodeId: nodeId, } } // Execute executes the request -// -// @return CanvasesUpdateNodePauseResponse +// @return CanvasesUpdateNodePauseResponse func (a *CanvasNodeAPIService) CanvasesUpdateNodePauseExecute(r ApiCanvasesUpdateNodePauseRequest) (*CanvasesUpdateNodePauseResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesUpdateNodePauseResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesUpdateNodePauseResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeAPIService.CanvasesUpdateNodePause") @@ -943,14 +937,14 @@ func (a *CanvasNodeAPIService) CanvasesUpdateNodePauseExecute(r ApiCanvasesUpdat body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_canvas_node_execution.go b/pkg/openapi_client/api_canvas_node_execution.go index 7bcef41e58..99375c8aeb 100644 --- a/pkg/openapi_client/api_canvas_node_execution.go +++ b/pkg/openapi_client/api_canvas_node_execution.go @@ -20,15 +20,16 @@ import ( "strings" ) + // CanvasNodeExecutionAPIService CanvasNodeExecutionAPI service type CanvasNodeExecutionAPIService service type ApiCanvasesCancelExecutionRequest struct { - ctx context.Context - ApiService *CanvasNodeExecutionAPIService - canvasId string + ctx context.Context + ApiService *CanvasNodeExecutionAPIService + canvasId string executionId string - body *map[string]interface{} + body *map[string]interface{} } func (r ApiCanvasesCancelExecutionRequest) Body(body map[string]interface{}) ApiCanvasesCancelExecutionRequest { @@ -45,29 +46,28 @@ CanvasesCancelExecution Cancel execution Cancels a running canvas node execution - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param executionId - @return ApiCanvasesCancelExecutionRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param executionId + @return ApiCanvasesCancelExecutionRequest */ func (a *CanvasNodeExecutionAPIService) CanvasesCancelExecution(ctx context.Context, canvasId string, executionId string) ApiCanvasesCancelExecutionRequest { return ApiCanvasesCancelExecutionRequest{ - ApiService: a, - ctx: ctx, - canvasId: canvasId, + ApiService: a, + ctx: ctx, + canvasId: canvasId, executionId: executionId, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *CanvasNodeExecutionAPIService) CanvasesCancelExecutionExecute(r ApiCanvasesCancelExecutionRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeExecutionAPIService.CanvasesCancelExecution") @@ -127,14 +127,14 @@ func (a *CanvasNodeExecutionAPIService) CanvasesCancelExecutionExecute(r ApiCanv body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -151,12 +151,12 @@ func (a *CanvasNodeExecutionAPIService) CanvasesCancelExecutionExecute(r ApiCanv } type ApiCanvasesInvokeNodeExecutionActionRequest struct { - ctx context.Context - ApiService *CanvasNodeExecutionAPIService - canvasId string + ctx context.Context + ApiService *CanvasNodeExecutionAPIService + canvasId string executionId string - actionName string - body *CanvasesInvokeNodeExecutionActionBody + actionName string + body *CanvasesInvokeNodeExecutionActionBody } func (r ApiCanvasesInvokeNodeExecutionActionRequest) Body(body CanvasesInvokeNodeExecutionActionBody) ApiCanvasesInvokeNodeExecutionActionRequest { @@ -173,31 +173,30 @@ CanvasesInvokeNodeExecutionAction Invoke execution action Invokes a custom action on a canvas node execution - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param executionId - @param actionName - @return ApiCanvasesInvokeNodeExecutionActionRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param executionId + @param actionName + @return ApiCanvasesInvokeNodeExecutionActionRequest */ func (a *CanvasNodeExecutionAPIService) CanvasesInvokeNodeExecutionAction(ctx context.Context, canvasId string, executionId string, actionName string) ApiCanvasesInvokeNodeExecutionActionRequest { return ApiCanvasesInvokeNodeExecutionActionRequest{ - ApiService: a, - ctx: ctx, - canvasId: canvasId, + ApiService: a, + ctx: ctx, + canvasId: canvasId, executionId: executionId, - actionName: actionName, + actionName: actionName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *CanvasNodeExecutionAPIService) CanvasesInvokeNodeExecutionActionExecute(r ApiCanvasesInvokeNodeExecutionActionRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeExecutionAPIService.CanvasesInvokeNodeExecutionAction") @@ -258,14 +257,14 @@ func (a *CanvasNodeExecutionAPIService) CanvasesInvokeNodeExecutionActionExecute body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -282,11 +281,11 @@ func (a *CanvasNodeExecutionAPIService) CanvasesInvokeNodeExecutionActionExecute } type ApiCanvasesListChildExecutionsRequest struct { - ctx context.Context - ApiService *CanvasNodeExecutionAPIService - canvasId string + ctx context.Context + ApiService *CanvasNodeExecutionAPIService + canvasId string executionId string - body *map[string]interface{} + body *map[string]interface{} } func (r ApiCanvasesListChildExecutionsRequest) Body(body map[string]interface{}) ApiCanvasesListChildExecutionsRequest { @@ -303,29 +302,28 @@ CanvasesListChildExecutions List child executions for an execution List child executions for an execution - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @param executionId - @return ApiCanvasesListChildExecutionsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @param executionId + @return ApiCanvasesListChildExecutionsRequest */ func (a *CanvasNodeExecutionAPIService) CanvasesListChildExecutions(ctx context.Context, canvasId string, executionId string) ApiCanvasesListChildExecutionsRequest { return ApiCanvasesListChildExecutionsRequest{ - ApiService: a, - ctx: ctx, - canvasId: canvasId, + ApiService: a, + ctx: ctx, + canvasId: canvasId, executionId: executionId, } } // Execute executes the request -// -// @return CanvasesListChildExecutionsResponse +// @return CanvasesListChildExecutionsResponse func (a *CanvasNodeExecutionAPIService) CanvasesListChildExecutionsExecute(r ApiCanvasesListChildExecutionsRequest) (*CanvasesListChildExecutionsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *CanvasesListChildExecutionsResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *CanvasesListChildExecutionsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeExecutionAPIService.CanvasesListChildExecutions") @@ -385,14 +383,14 @@ func (a *CanvasNodeExecutionAPIService) CanvasesListChildExecutionsExecute(r Api body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -409,10 +407,10 @@ func (a *CanvasNodeExecutionAPIService) CanvasesListChildExecutionsExecute(r Api } type ApiCanvasesResolveExecutionErrorsRequest struct { - ctx context.Context + ctx context.Context ApiService *CanvasNodeExecutionAPIService - canvasId string - body *CanvasesResolveExecutionErrorsBody + canvasId string + body *CanvasesResolveExecutionErrorsBody } func (r ApiCanvasesResolveExecutionErrorsRequest) Body(body CanvasesResolveExecutionErrorsBody) ApiCanvasesResolveExecutionErrorsRequest { @@ -429,27 +427,26 @@ CanvasesResolveExecutionErrors Resolve execution errors Marks canvas node execution errors as resolved - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param canvasId - @return ApiCanvasesResolveExecutionErrorsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param canvasId + @return ApiCanvasesResolveExecutionErrorsRequest */ func (a *CanvasNodeExecutionAPIService) CanvasesResolveExecutionErrors(ctx context.Context, canvasId string) ApiCanvasesResolveExecutionErrorsRequest { return ApiCanvasesResolveExecutionErrorsRequest{ ApiService: a, - ctx: ctx, - canvasId: canvasId, + ctx: ctx, + canvasId: canvasId, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *CanvasNodeExecutionAPIService) CanvasesResolveExecutionErrorsExecute(r ApiCanvasesResolveExecutionErrorsRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "CanvasNodeExecutionAPIService.CanvasesResolveExecutionErrors") @@ -508,14 +505,14 @@ func (a *CanvasNodeExecutionAPIService) CanvasesResolveExecutionErrorsExecute(r body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_component.go b/pkg/openapi_client/api_component.go index 8905ad44eb..93f500f6aa 100644 --- a/pkg/openapi_client/api_component.go +++ b/pkg/openapi_client/api_component.go @@ -20,13 +20,14 @@ import ( "strings" ) + // ComponentAPIService ComponentAPI service type ComponentAPIService service type ApiComponentsDescribeComponentRequest struct { - ctx context.Context + ctx context.Context ApiService *ComponentAPIService - name string + name string } func (r ApiComponentsDescribeComponentRequest) Execute() (*ComponentsDescribeComponentResponse, *http.Response, error) { @@ -38,27 +39,26 @@ ComponentsDescribeComponent Describe component Returns a component by its name - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param name - @return ApiComponentsDescribeComponentRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param name + @return ApiComponentsDescribeComponentRequest */ func (a *ComponentAPIService) ComponentsDescribeComponent(ctx context.Context, name string) ApiComponentsDescribeComponentRequest { return ApiComponentsDescribeComponentRequest{ ApiService: a, - ctx: ctx, - name: name, + ctx: ctx, + name: name, } } // Execute executes the request -// -// @return ComponentsDescribeComponentResponse +// @return ComponentsDescribeComponentResponse func (a *ComponentAPIService) ComponentsDescribeComponentExecute(r ApiComponentsDescribeComponentRequest) (*ComponentsDescribeComponentResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ComponentsDescribeComponentResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ComponentsDescribeComponentResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ComponentAPIService.ComponentsDescribeComponent") @@ -112,14 +112,14 @@ func (a *ComponentAPIService) ComponentsDescribeComponentExecute(r ApiComponents body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -136,9 +136,9 @@ func (a *ComponentAPIService) ComponentsDescribeComponentExecute(r ApiComponents } type ApiComponentsListComponentActionsRequest struct { - ctx context.Context + ctx context.Context ApiService *ComponentAPIService - name string + name string } func (r ApiComponentsListComponentActionsRequest) Execute() (*ComponentsListComponentActionsResponse, *http.Response, error) { @@ -150,27 +150,26 @@ ComponentsListComponentActions List component actions Returns available actions for a component - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param name - @return ApiComponentsListComponentActionsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param name + @return ApiComponentsListComponentActionsRequest */ func (a *ComponentAPIService) ComponentsListComponentActions(ctx context.Context, name string) ApiComponentsListComponentActionsRequest { return ApiComponentsListComponentActionsRequest{ ApiService: a, - ctx: ctx, - name: name, + ctx: ctx, + name: name, } } // Execute executes the request -// -// @return ComponentsListComponentActionsResponse +// @return ComponentsListComponentActionsResponse func (a *ComponentAPIService) ComponentsListComponentActionsExecute(r ApiComponentsListComponentActionsRequest) (*ComponentsListComponentActionsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ComponentsListComponentActionsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ComponentsListComponentActionsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ComponentAPIService.ComponentsListComponentActions") @@ -224,14 +223,14 @@ func (a *ComponentAPIService) ComponentsListComponentActionsExecute(r ApiCompone body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -248,7 +247,7 @@ func (a *ComponentAPIService) ComponentsListComponentActionsExecute(r ApiCompone } type ApiComponentsListComponentsRequest struct { - ctx context.Context + ctx context.Context ApiService *ComponentAPIService } @@ -261,25 +260,24 @@ ComponentsListComponents List components Returns a list of all components - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiComponentsListComponentsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiComponentsListComponentsRequest */ func (a *ComponentAPIService) ComponentsListComponents(ctx context.Context) ApiComponentsListComponentsRequest { return ApiComponentsListComponentsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return ComponentsListComponentsResponse +// @return ComponentsListComponentsResponse func (a *ComponentAPIService) ComponentsListComponentsExecute(r ApiComponentsListComponentsRequest) (*ComponentsListComponentsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ComponentsListComponentsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ComponentsListComponentsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ComponentAPIService.ComponentsListComponents") @@ -332,14 +330,14 @@ func (a *ComponentAPIService) ComponentsListComponentsExecute(r ApiComponentsLis body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_groups.go b/pkg/openapi_client/api_groups.go index d57d9a2710..1c76d83360 100644 --- a/pkg/openapi_client/api_groups.go +++ b/pkg/openapi_client/api_groups.go @@ -20,14 +20,15 @@ import ( "strings" ) + // GroupsAPIService GroupsAPI service type GroupsAPIService service type ApiGroupsAddUserToGroupRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - groupName string - body *GroupsAddUserToGroupBody + groupName string + body *GroupsAddUserToGroupBody } func (r ApiGroupsAddUserToGroupRequest) Body(body GroupsAddUserToGroupBody) ApiGroupsAddUserToGroupRequest { @@ -44,27 +45,26 @@ GroupsAddUserToGroup Add user to group Adds a user to a group within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param groupName - @return ApiGroupsAddUserToGroupRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param groupName + @return ApiGroupsAddUserToGroupRequest */ func (a *GroupsAPIService) GroupsAddUserToGroup(ctx context.Context, groupName string) ApiGroupsAddUserToGroupRequest { return ApiGroupsAddUserToGroupRequest{ ApiService: a, - ctx: ctx, - groupName: groupName, + ctx: ctx, + groupName: groupName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *GroupsAPIService) GroupsAddUserToGroupExecute(r ApiGroupsAddUserToGroupRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsAddUserToGroup") @@ -123,14 +123,14 @@ func (a *GroupsAPIService) GroupsAddUserToGroupExecute(r ApiGroupsAddUserToGroup body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -147,9 +147,9 @@ func (a *GroupsAPIService) GroupsAddUserToGroupExecute(r ApiGroupsAddUserToGroup } type ApiGroupsCreateGroupRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - body *GroupsCreateGroupRequest + body *GroupsCreateGroupRequest } func (r ApiGroupsCreateGroupRequest) Body(body GroupsCreateGroupRequest) ApiGroupsCreateGroupRequest { @@ -166,25 +166,24 @@ GroupsCreateGroup Create group Creates a new group within a domain with a specific role - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiGroupsCreateGroupRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGroupsCreateGroupRequest */ func (a *GroupsAPIService) GroupsCreateGroup(ctx context.Context) ApiGroupsCreateGroupRequest { return ApiGroupsCreateGroupRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return GroupsCreateGroupResponse +// @return GroupsCreateGroupResponse func (a *GroupsAPIService) GroupsCreateGroupExecute(r ApiGroupsCreateGroupRequest) (*GroupsCreateGroupResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GroupsCreateGroupResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GroupsCreateGroupResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsCreateGroup") @@ -242,14 +241,14 @@ func (a *GroupsAPIService) GroupsCreateGroupExecute(r ApiGroupsCreateGroupReques body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -266,11 +265,11 @@ func (a *GroupsAPIService) GroupsCreateGroupExecute(r ApiGroupsCreateGroupReques } type ApiGroupsDeleteGroupRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - groupName string + groupName string domainType *string - domainId *string + domainId *string } func (r ApiGroupsDeleteGroupRequest) DomainType(domainType string) ApiGroupsDeleteGroupRequest { @@ -292,27 +291,26 @@ GroupsDeleteGroup Delete group Deletes an existing group within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param groupName - @return ApiGroupsDeleteGroupRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param groupName + @return ApiGroupsDeleteGroupRequest */ func (a *GroupsAPIService) GroupsDeleteGroup(ctx context.Context, groupName string) ApiGroupsDeleteGroupRequest { return ApiGroupsDeleteGroupRequest{ ApiService: a, - ctx: ctx, - groupName: groupName, + ctx: ctx, + groupName: groupName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *GroupsAPIService) GroupsDeleteGroupExecute(r ApiGroupsDeleteGroupRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsDeleteGroup") @@ -375,14 +373,14 @@ func (a *GroupsAPIService) GroupsDeleteGroupExecute(r ApiGroupsDeleteGroupReques body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -399,11 +397,11 @@ func (a *GroupsAPIService) GroupsDeleteGroupExecute(r ApiGroupsDeleteGroupReques } type ApiGroupsDescribeGroupRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - groupName string + groupName string domainType *string - domainId *string + domainId *string } func (r ApiGroupsDescribeGroupRequest) DomainType(domainType string) ApiGroupsDescribeGroupRequest { @@ -425,27 +423,26 @@ GroupsDescribeGroup Get group Returns details of a specific group within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param groupName - @return ApiGroupsDescribeGroupRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param groupName + @return ApiGroupsDescribeGroupRequest */ func (a *GroupsAPIService) GroupsDescribeGroup(ctx context.Context, groupName string) ApiGroupsDescribeGroupRequest { return ApiGroupsDescribeGroupRequest{ ApiService: a, - ctx: ctx, - groupName: groupName, + ctx: ctx, + groupName: groupName, } } // Execute executes the request -// -// @return GroupsDescribeGroupResponse +// @return GroupsDescribeGroupResponse func (a *GroupsAPIService) GroupsDescribeGroupExecute(r ApiGroupsDescribeGroupRequest) (*GroupsDescribeGroupResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GroupsDescribeGroupResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GroupsDescribeGroupResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsDescribeGroup") @@ -508,14 +505,14 @@ func (a *GroupsAPIService) GroupsDescribeGroupExecute(r ApiGroupsDescribeGroupRe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -532,11 +529,11 @@ func (a *GroupsAPIService) GroupsDescribeGroupExecute(r ApiGroupsDescribeGroupRe } type ApiGroupsListGroupUsersRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - groupName string + groupName string domainType *string - domainId *string + domainId *string } func (r ApiGroupsListGroupUsersRequest) DomainType(domainType string) ApiGroupsListGroupUsersRequest { @@ -558,27 +555,26 @@ GroupsListGroupUsers Get group users Returns users that belong to a specific group within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param groupName - @return ApiGroupsListGroupUsersRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param groupName + @return ApiGroupsListGroupUsersRequest */ func (a *GroupsAPIService) GroupsListGroupUsers(ctx context.Context, groupName string) ApiGroupsListGroupUsersRequest { return ApiGroupsListGroupUsersRequest{ ApiService: a, - ctx: ctx, - groupName: groupName, + ctx: ctx, + groupName: groupName, } } // Execute executes the request -// -// @return GroupsListGroupUsersResponse +// @return GroupsListGroupUsersResponse func (a *GroupsAPIService) GroupsListGroupUsersExecute(r ApiGroupsListGroupUsersRequest) (*GroupsListGroupUsersResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GroupsListGroupUsersResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GroupsListGroupUsersResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsListGroupUsers") @@ -641,14 +637,14 @@ func (a *GroupsAPIService) GroupsListGroupUsersExecute(r ApiGroupsListGroupUsers body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -665,10 +661,10 @@ func (a *GroupsAPIService) GroupsListGroupUsersExecute(r ApiGroupsListGroupUsers } type ApiGroupsListGroupsRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService domainType *string - domainId *string + domainId *string } func (r ApiGroupsListGroupsRequest) DomainType(domainType string) ApiGroupsListGroupsRequest { @@ -690,25 +686,24 @@ GroupsListGroups List groups Returns a list of groups within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiGroupsListGroupsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGroupsListGroupsRequest */ func (a *GroupsAPIService) GroupsListGroups(ctx context.Context) ApiGroupsListGroupsRequest { return ApiGroupsListGroupsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return GroupsListGroupsResponse +// @return GroupsListGroupsResponse func (a *GroupsAPIService) GroupsListGroupsExecute(r ApiGroupsListGroupsRequest) (*GroupsListGroupsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GroupsListGroupsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GroupsListGroupsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsListGroups") @@ -770,14 +765,14 @@ func (a *GroupsAPIService) GroupsListGroupsExecute(r ApiGroupsListGroupsRequest) body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -794,10 +789,10 @@ func (a *GroupsAPIService) GroupsListGroupsExecute(r ApiGroupsListGroupsRequest) } type ApiGroupsRemoveUserFromGroupRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - groupName string - body *GroupsRemoveUserFromGroupBody + groupName string + body *GroupsRemoveUserFromGroupBody } func (r ApiGroupsRemoveUserFromGroupRequest) Body(body GroupsRemoveUserFromGroupBody) ApiGroupsRemoveUserFromGroupRequest { @@ -814,27 +809,26 @@ GroupsRemoveUserFromGroup Remove user from group Removes a user from a group within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param groupName - @return ApiGroupsRemoveUserFromGroupRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param groupName + @return ApiGroupsRemoveUserFromGroupRequest */ func (a *GroupsAPIService) GroupsRemoveUserFromGroup(ctx context.Context, groupName string) ApiGroupsRemoveUserFromGroupRequest { return ApiGroupsRemoveUserFromGroupRequest{ ApiService: a, - ctx: ctx, - groupName: groupName, + ctx: ctx, + groupName: groupName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *GroupsAPIService) GroupsRemoveUserFromGroupExecute(r ApiGroupsRemoveUserFromGroupRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsRemoveUserFromGroup") @@ -893,14 +887,14 @@ func (a *GroupsAPIService) GroupsRemoveUserFromGroupExecute(r ApiGroupsRemoveUse body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -917,10 +911,10 @@ func (a *GroupsAPIService) GroupsRemoveUserFromGroupExecute(r ApiGroupsRemoveUse } type ApiGroupsUpdateGroupRequest struct { - ctx context.Context + ctx context.Context ApiService *GroupsAPIService - groupName string - body *GroupsUpdateGroupBody + groupName string + body *GroupsUpdateGroupBody } func (r ApiGroupsUpdateGroupRequest) Body(body GroupsUpdateGroupBody) ApiGroupsUpdateGroupRequest { @@ -937,27 +931,26 @@ GroupsUpdateGroup Update group Updates an existing group within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param groupName - @return ApiGroupsUpdateGroupRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param groupName + @return ApiGroupsUpdateGroupRequest */ func (a *GroupsAPIService) GroupsUpdateGroup(ctx context.Context, groupName string) ApiGroupsUpdateGroupRequest { return ApiGroupsUpdateGroupRequest{ ApiService: a, - ctx: ctx, - groupName: groupName, + ctx: ctx, + groupName: groupName, } } // Execute executes the request -// -// @return GroupsUpdateGroupResponse +// @return GroupsUpdateGroupResponse func (a *GroupsAPIService) GroupsUpdateGroupExecute(r ApiGroupsUpdateGroupRequest) (*GroupsUpdateGroupResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GroupsUpdateGroupResponse + localVarHTTPMethod = http.MethodPut + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GroupsUpdateGroupResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GroupsAPIService.GroupsUpdateGroup") @@ -1016,14 +1009,14 @@ func (a *GroupsAPIService) GroupsUpdateGroupExecute(r ApiGroupsUpdateGroupReques body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_integration.go b/pkg/openapi_client/api_integration.go index 6b0f29b118..805496b062 100644 --- a/pkg/openapi_client/api_integration.go +++ b/pkg/openapi_client/api_integration.go @@ -19,11 +19,12 @@ import ( "net/url" ) + // IntegrationAPIService IntegrationAPI service type IntegrationAPIService service type ApiIntegrationsListIntegrationsRequest struct { - ctx context.Context + ctx context.Context ApiService *IntegrationAPIService } @@ -36,25 +37,24 @@ IntegrationsListIntegrations List available integrations List available integrations - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiIntegrationsListIntegrationsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiIntegrationsListIntegrationsRequest */ func (a *IntegrationAPIService) IntegrationsListIntegrations(ctx context.Context) ApiIntegrationsListIntegrationsRequest { return ApiIntegrationsListIntegrationsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return SuperplaneIntegrationsListIntegrationsResponse +// @return SuperplaneIntegrationsListIntegrationsResponse func (a *IntegrationAPIService) IntegrationsListIntegrationsExecute(r ApiIntegrationsListIntegrationsRequest) (*SuperplaneIntegrationsListIntegrationsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SuperplaneIntegrationsListIntegrationsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SuperplaneIntegrationsListIntegrationsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "IntegrationAPIService.IntegrationsListIntegrations") @@ -107,14 +107,14 @@ func (a *IntegrationAPIService) IntegrationsListIntegrationsExecute(r ApiIntegra body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_me.go b/pkg/openapi_client/api_me.go index 166c352d59..57b8e11ce2 100644 --- a/pkg/openapi_client/api_me.go +++ b/pkg/openapi_client/api_me.go @@ -19,11 +19,12 @@ import ( "net/url" ) + // MeAPIService MeAPI service type MeAPIService service type ApiMeMeRequest struct { - ctx context.Context + ctx context.Context ApiService *MeAPIService } @@ -36,25 +37,24 @@ MeMe Get current user Returns the currently authenticated user - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiMeMeRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiMeMeRequest */ func (a *MeAPIService) MeMe(ctx context.Context) ApiMeMeRequest { return ApiMeMeRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return SuperplaneMeUser +// @return SuperplaneMeUser func (a *MeAPIService) MeMeExecute(r ApiMeMeRequest) (*SuperplaneMeUser, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SuperplaneMeUser + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SuperplaneMeUser ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIService.MeMe") @@ -107,14 +107,14 @@ func (a *MeAPIService) MeMeExecute(r ApiMeMeRequest) (*SuperplaneMeUser, *http.R body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -131,7 +131,7 @@ func (a *MeAPIService) MeMeExecute(r ApiMeMeRequest) (*SuperplaneMeUser, *http.R } type ApiMeRegenerateTokenRequest struct { - ctx context.Context + ctx context.Context ApiService *MeAPIService } @@ -144,25 +144,24 @@ MeRegenerateToken Regenerate API token Regenerates the currently authencated user's API token - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiMeRegenerateTokenRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiMeRegenerateTokenRequest */ func (a *MeAPIService) MeRegenerateToken(ctx context.Context) ApiMeRegenerateTokenRequest { return ApiMeRegenerateTokenRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return MeRegenerateTokenResponse +// @return MeRegenerateTokenResponse func (a *MeAPIService) MeRegenerateTokenExecute(r ApiMeRegenerateTokenRequest) (*MeRegenerateTokenResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *MeRegenerateTokenResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *MeRegenerateTokenResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeAPIService.MeRegenerateToken") @@ -215,14 +214,14 @@ func (a *MeAPIService) MeRegenerateTokenExecute(r ApiMeRegenerateTokenRequest) ( body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_organization.go b/pkg/openapi_client/api_organization.go index 763b12a21a..bee176c0d7 100644 --- a/pkg/openapi_client/api_organization.go +++ b/pkg/openapi_client/api_organization.go @@ -21,18 +21,19 @@ import ( "time" ) + // OrganizationAPIService OrganizationAPI service type OrganizationAPIService service type ApiOrganizationsAcceptInviteLinkRequest struct { - ctx context.Context - ApiService *OrganizationAPIService - token string - id *string + ctx context.Context + ApiService *OrganizationAPIService + token string + id *string organizationId *string - enabled *bool - createdAt *time.Time - updatedAt *time.Time + enabled *bool + createdAt *time.Time + updatedAt *time.Time } func (r ApiOrganizationsAcceptInviteLinkRequest) Id(id string) ApiOrganizationsAcceptInviteLinkRequest { @@ -69,27 +70,26 @@ OrganizationsAcceptInviteLink Accept an invite link Accepts an organization invite link for the authenticated account - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param token - @return ApiOrganizationsAcceptInviteLinkRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param token + @return ApiOrganizationsAcceptInviteLinkRequest */ func (a *OrganizationAPIService) OrganizationsAcceptInviteLink(ctx context.Context, token string) ApiOrganizationsAcceptInviteLinkRequest { return ApiOrganizationsAcceptInviteLinkRequest{ ApiService: a, - ctx: ctx, - token: token, + ctx: ctx, + token: token, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *OrganizationAPIService) OrganizationsAcceptInviteLinkExecute(r ApiOrganizationsAcceptInviteLinkRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsAcceptInviteLink") @@ -158,14 +158,14 @@ func (a *OrganizationAPIService) OrganizationsAcceptInviteLinkExecute(r ApiOrgan body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -182,10 +182,10 @@ func (a *OrganizationAPIService) OrganizationsAcceptInviteLinkExecute(r ApiOrgan } type ApiOrganizationsCreateIntegrationRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string - body *OrganizationsCreateIntegrationBody + id string + body *OrganizationsCreateIntegrationBody } func (r ApiOrganizationsCreateIntegrationRequest) Body(body OrganizationsCreateIntegrationBody) ApiOrganizationsCreateIntegrationRequest { @@ -202,27 +202,26 @@ OrganizationsCreateIntegration Create organization integration Create an organization integration - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsCreateIntegrationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsCreateIntegrationRequest */ func (a *OrganizationAPIService) OrganizationsCreateIntegration(ctx context.Context, id string) ApiOrganizationsCreateIntegrationRequest { return ApiOrganizationsCreateIntegrationRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsCreateIntegrationResponse +// @return OrganizationsCreateIntegrationResponse func (a *OrganizationAPIService) OrganizationsCreateIntegrationExecute(r ApiOrganizationsCreateIntegrationRequest) (*OrganizationsCreateIntegrationResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsCreateIntegrationResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsCreateIntegrationResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsCreateIntegration") @@ -281,14 +280,14 @@ func (a *OrganizationAPIService) OrganizationsCreateIntegrationExecute(r ApiOrga body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -305,10 +304,10 @@ func (a *OrganizationAPIService) OrganizationsCreateIntegrationExecute(r ApiOrga } type ApiOrganizationsCreateInvitationRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string - body *OrganizationsCreateInvitationBody + id string + body *OrganizationsCreateInvitationBody } func (r ApiOrganizationsCreateInvitationRequest) Body(body OrganizationsCreateInvitationBody) ApiOrganizationsCreateInvitationRequest { @@ -325,27 +324,26 @@ OrganizationsCreateInvitation Create an organization invitation Invites a user to join an organization by email - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsCreateInvitationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsCreateInvitationRequest */ func (a *OrganizationAPIService) OrganizationsCreateInvitation(ctx context.Context, id string) ApiOrganizationsCreateInvitationRequest { return ApiOrganizationsCreateInvitationRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsCreateInvitationResponse +// @return OrganizationsCreateInvitationResponse func (a *OrganizationAPIService) OrganizationsCreateInvitationExecute(r ApiOrganizationsCreateInvitationRequest) (*OrganizationsCreateInvitationResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsCreateInvitationResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsCreateInvitationResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsCreateInvitation") @@ -404,14 +402,14 @@ func (a *OrganizationAPIService) OrganizationsCreateInvitationExecute(r ApiOrgan body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -428,9 +426,9 @@ func (a *OrganizationAPIService) OrganizationsCreateInvitationExecute(r ApiOrgan } type ApiOrganizationsDeleteIntegrationRequest struct { - ctx context.Context - ApiService *OrganizationAPIService - id string + ctx context.Context + ApiService *OrganizationAPIService + id string integrationId string } @@ -443,29 +441,28 @@ OrganizationsDeleteIntegration Delete organization integration Deletes an integration from an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @param integrationId - @return ApiOrganizationsDeleteIntegrationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @param integrationId + @return ApiOrganizationsDeleteIntegrationRequest */ func (a *OrganizationAPIService) OrganizationsDeleteIntegration(ctx context.Context, id string, integrationId string) ApiOrganizationsDeleteIntegrationRequest { return ApiOrganizationsDeleteIntegrationRequest{ - ApiService: a, - ctx: ctx, - id: id, + ApiService: a, + ctx: ctx, + id: id, integrationId: integrationId, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *OrganizationAPIService) OrganizationsDeleteIntegrationExecute(r ApiOrganizationsDeleteIntegrationRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsDeleteIntegration") @@ -520,14 +517,14 @@ func (a *OrganizationAPIService) OrganizationsDeleteIntegrationExecute(r ApiOrga body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -544,9 +541,9 @@ func (a *OrganizationAPIService) OrganizationsDeleteIntegrationExecute(r ApiOrga } type ApiOrganizationsDeleteOrganizationRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string + id string } func (r ApiOrganizationsDeleteOrganizationRequest) Execute() (map[string]interface{}, *http.Response, error) { @@ -558,27 +555,26 @@ OrganizationsDeleteOrganization Delete an organization Deletes the specified organization (can be referenced by ID or name) - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsDeleteOrganizationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsDeleteOrganizationRequest */ func (a *OrganizationAPIService) OrganizationsDeleteOrganization(ctx context.Context, id string) ApiOrganizationsDeleteOrganizationRequest { return ApiOrganizationsDeleteOrganizationRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *OrganizationAPIService) OrganizationsDeleteOrganizationExecute(r ApiOrganizationsDeleteOrganizationRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsDeleteOrganization") @@ -632,14 +628,14 @@ func (a *OrganizationAPIService) OrganizationsDeleteOrganizationExecute(r ApiOrg body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -656,9 +652,9 @@ func (a *OrganizationAPIService) OrganizationsDeleteOrganizationExecute(r ApiOrg } type ApiOrganizationsDescribeIntegrationRequest struct { - ctx context.Context - ApiService *OrganizationAPIService - id string + ctx context.Context + ApiService *OrganizationAPIService + id string integrationId string } @@ -671,29 +667,28 @@ OrganizationsDescribeIntegration Describe an integration in an organization Returns details of a specific integration in an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @param integrationId - @return ApiOrganizationsDescribeIntegrationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @param integrationId + @return ApiOrganizationsDescribeIntegrationRequest */ func (a *OrganizationAPIService) OrganizationsDescribeIntegration(ctx context.Context, id string, integrationId string) ApiOrganizationsDescribeIntegrationRequest { return ApiOrganizationsDescribeIntegrationRequest{ - ApiService: a, - ctx: ctx, - id: id, + ApiService: a, + ctx: ctx, + id: id, integrationId: integrationId, } } // Execute executes the request -// -// @return OrganizationsDescribeIntegrationResponse +// @return OrganizationsDescribeIntegrationResponse func (a *OrganizationAPIService) OrganizationsDescribeIntegrationExecute(r ApiOrganizationsDescribeIntegrationRequest) (*OrganizationsDescribeIntegrationResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsDescribeIntegrationResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsDescribeIntegrationResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsDescribeIntegration") @@ -748,14 +743,14 @@ func (a *OrganizationAPIService) OrganizationsDescribeIntegrationExecute(r ApiOr body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -772,9 +767,9 @@ func (a *OrganizationAPIService) OrganizationsDescribeIntegrationExecute(r ApiOr } type ApiOrganizationsDescribeOrganizationRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string + id string } func (r ApiOrganizationsDescribeOrganizationRequest) Execute() (*OrganizationsDescribeOrganizationResponse, *http.Response, error) { @@ -786,27 +781,26 @@ OrganizationsDescribeOrganization Get organization details Returns the details of a specific organization (can be referenced by ID or name) - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsDescribeOrganizationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsDescribeOrganizationRequest */ func (a *OrganizationAPIService) OrganizationsDescribeOrganization(ctx context.Context, id string) ApiOrganizationsDescribeOrganizationRequest { return ApiOrganizationsDescribeOrganizationRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsDescribeOrganizationResponse +// @return OrganizationsDescribeOrganizationResponse func (a *OrganizationAPIService) OrganizationsDescribeOrganizationExecute(r ApiOrganizationsDescribeOrganizationRequest) (*OrganizationsDescribeOrganizationResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsDescribeOrganizationResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsDescribeOrganizationResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsDescribeOrganization") @@ -860,14 +854,14 @@ func (a *OrganizationAPIService) OrganizationsDescribeOrganizationExecute(r ApiO body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -884,9 +878,9 @@ func (a *OrganizationAPIService) OrganizationsDescribeOrganizationExecute(r ApiO } type ApiOrganizationsGetInviteLinkRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string + id string } func (r ApiOrganizationsGetInviteLinkRequest) Execute() (*OrganizationsGetInviteLinkResponse, *http.Response, error) { @@ -898,27 +892,26 @@ OrganizationsGetInviteLink Get an organization invite link Returns the invite link for an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsGetInviteLinkRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsGetInviteLinkRequest */ func (a *OrganizationAPIService) OrganizationsGetInviteLink(ctx context.Context, id string) ApiOrganizationsGetInviteLinkRequest { return ApiOrganizationsGetInviteLinkRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsGetInviteLinkResponse +// @return OrganizationsGetInviteLinkResponse func (a *OrganizationAPIService) OrganizationsGetInviteLinkExecute(r ApiOrganizationsGetInviteLinkRequest) (*OrganizationsGetInviteLinkResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsGetInviteLinkResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsGetInviteLinkResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsGetInviteLink") @@ -972,14 +965,14 @@ func (a *OrganizationAPIService) OrganizationsGetInviteLinkExecute(r ApiOrganiza body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -996,11 +989,11 @@ func (a *OrganizationAPIService) OrganizationsGetInviteLinkExecute(r ApiOrganiza } type ApiOrganizationsListIntegrationResourcesRequest struct { - ctx context.Context - ApiService *OrganizationAPIService - id string + ctx context.Context + ApiService *OrganizationAPIService + id string integrationId string - parameters *string + parameters *string } func (r ApiOrganizationsListIntegrationResourcesRequest) Parameters(parameters string) ApiOrganizationsListIntegrationResourcesRequest { @@ -1017,29 +1010,28 @@ OrganizationsListIntegrationResources List integration resources Lists resources for an integration - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @param integrationId - @return ApiOrganizationsListIntegrationResourcesRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @param integrationId + @return ApiOrganizationsListIntegrationResourcesRequest */ func (a *OrganizationAPIService) OrganizationsListIntegrationResources(ctx context.Context, id string, integrationId string) ApiOrganizationsListIntegrationResourcesRequest { return ApiOrganizationsListIntegrationResourcesRequest{ - ApiService: a, - ctx: ctx, - id: id, + ApiService: a, + ctx: ctx, + id: id, integrationId: integrationId, } } // Execute executes the request -// -// @return OrganizationsListIntegrationResourcesResponse +// @return OrganizationsListIntegrationResourcesResponse func (a *OrganizationAPIService) OrganizationsListIntegrationResourcesExecute(r ApiOrganizationsListIntegrationResourcesRequest) (*OrganizationsListIntegrationResourcesResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsListIntegrationResourcesResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsListIntegrationResourcesResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsListIntegrationResources") @@ -1097,14 +1089,14 @@ func (a *OrganizationAPIService) OrganizationsListIntegrationResourcesExecute(r body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1121,9 +1113,9 @@ func (a *OrganizationAPIService) OrganizationsListIntegrationResourcesExecute(r } type ApiOrganizationsListIntegrationsRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string + id string } func (r ApiOrganizationsListIntegrationsRequest) Execute() (*SuperplaneOrganizationsListIntegrationsResponse, *http.Response, error) { @@ -1135,27 +1127,26 @@ OrganizationsListIntegrations List integrations in an organization Returns a list of integrations in an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsListIntegrationsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsListIntegrationsRequest */ func (a *OrganizationAPIService) OrganizationsListIntegrations(ctx context.Context, id string) ApiOrganizationsListIntegrationsRequest { return ApiOrganizationsListIntegrationsRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return SuperplaneOrganizationsListIntegrationsResponse +// @return SuperplaneOrganizationsListIntegrationsResponse func (a *OrganizationAPIService) OrganizationsListIntegrationsExecute(r ApiOrganizationsListIntegrationsRequest) (*SuperplaneOrganizationsListIntegrationsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SuperplaneOrganizationsListIntegrationsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SuperplaneOrganizationsListIntegrationsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsListIntegrations") @@ -1209,14 +1200,14 @@ func (a *OrganizationAPIService) OrganizationsListIntegrationsExecute(r ApiOrgan body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1233,9 +1224,9 @@ func (a *OrganizationAPIService) OrganizationsListIntegrationsExecute(r ApiOrgan } type ApiOrganizationsListInvitationsRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string + id string } func (r ApiOrganizationsListInvitationsRequest) Execute() (*OrganizationsListInvitationsResponse, *http.Response, error) { @@ -1247,27 +1238,26 @@ OrganizationsListInvitations List organization invitations Returns pending invitations for an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsListInvitationsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsListInvitationsRequest */ func (a *OrganizationAPIService) OrganizationsListInvitations(ctx context.Context, id string) ApiOrganizationsListInvitationsRequest { return ApiOrganizationsListInvitationsRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsListInvitationsResponse +// @return OrganizationsListInvitationsResponse func (a *OrganizationAPIService) OrganizationsListInvitationsExecute(r ApiOrganizationsListInvitationsRequest) (*OrganizationsListInvitationsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsListInvitationsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsListInvitationsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsListInvitations") @@ -1321,14 +1311,14 @@ func (a *OrganizationAPIService) OrganizationsListInvitationsExecute(r ApiOrgani body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1345,9 +1335,9 @@ func (a *OrganizationAPIService) OrganizationsListInvitationsExecute(r ApiOrgani } type ApiOrganizationsRemoveInvitationRequest struct { - ctx context.Context - ApiService *OrganizationAPIService - id string + ctx context.Context + ApiService *OrganizationAPIService + id string invitationId string } @@ -1360,29 +1350,28 @@ OrganizationsRemoveInvitation Remove an organization invitation Removes an organization invitation - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @param invitationId - @return ApiOrganizationsRemoveInvitationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @param invitationId + @return ApiOrganizationsRemoveInvitationRequest */ func (a *OrganizationAPIService) OrganizationsRemoveInvitation(ctx context.Context, id string, invitationId string) ApiOrganizationsRemoveInvitationRequest { return ApiOrganizationsRemoveInvitationRequest{ - ApiService: a, - ctx: ctx, - id: id, + ApiService: a, + ctx: ctx, + id: id, invitationId: invitationId, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *OrganizationAPIService) OrganizationsRemoveInvitationExecute(r ApiOrganizationsRemoveInvitationRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsRemoveInvitation") @@ -1437,14 +1426,14 @@ func (a *OrganizationAPIService) OrganizationsRemoveInvitationExecute(r ApiOrgan body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1461,10 +1450,10 @@ func (a *OrganizationAPIService) OrganizationsRemoveInvitationExecute(r ApiOrgan } type ApiOrganizationsRemoveUserRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string - userId string + id string + userId string } func (r ApiOrganizationsRemoveUserRequest) Execute() (map[string]interface{}, *http.Response, error) { @@ -1476,29 +1465,28 @@ OrganizationsRemoveUser Remove a user from an organization Removes a user from an organization (can be referenced by ID or name) - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @param userId - @return ApiOrganizationsRemoveUserRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @param userId + @return ApiOrganizationsRemoveUserRequest */ func (a *OrganizationAPIService) OrganizationsRemoveUser(ctx context.Context, id string, userId string) ApiOrganizationsRemoveUserRequest { return ApiOrganizationsRemoveUserRequest{ ApiService: a, - ctx: ctx, - id: id, - userId: userId, + ctx: ctx, + id: id, + userId: userId, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *OrganizationAPIService) OrganizationsRemoveUserExecute(r ApiOrganizationsRemoveUserRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsRemoveUser") @@ -1553,14 +1541,14 @@ func (a *OrganizationAPIService) OrganizationsRemoveUserExecute(r ApiOrganizatio body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1577,9 +1565,9 @@ func (a *OrganizationAPIService) OrganizationsRemoveUserExecute(r ApiOrganizatio } type ApiOrganizationsResetInviteLinkRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string + id string } func (r ApiOrganizationsResetInviteLinkRequest) Execute() (*OrganizationsResetInviteLinkResponse, *http.Response, error) { @@ -1591,27 +1579,26 @@ OrganizationsResetInviteLink Reset an organization invite link Generates a new invite link token for an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsResetInviteLinkRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsResetInviteLinkRequest */ func (a *OrganizationAPIService) OrganizationsResetInviteLink(ctx context.Context, id string) ApiOrganizationsResetInviteLinkRequest { return ApiOrganizationsResetInviteLinkRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsResetInviteLinkResponse +// @return OrganizationsResetInviteLinkResponse func (a *OrganizationAPIService) OrganizationsResetInviteLinkExecute(r ApiOrganizationsResetInviteLinkRequest) (*OrganizationsResetInviteLinkResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsResetInviteLinkResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsResetInviteLinkResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsResetInviteLink") @@ -1665,14 +1652,14 @@ func (a *OrganizationAPIService) OrganizationsResetInviteLinkExecute(r ApiOrgani body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1689,11 +1676,11 @@ func (a *OrganizationAPIService) OrganizationsResetInviteLinkExecute(r ApiOrgani } type ApiOrganizationsUpdateIntegrationRequest struct { - ctx context.Context - ApiService *OrganizationAPIService - id string + ctx context.Context + ApiService *OrganizationAPIService + id string integrationId string - body *OrganizationsUpdateIntegrationBody + body *OrganizationsUpdateIntegrationBody } func (r ApiOrganizationsUpdateIntegrationRequest) Body(body OrganizationsUpdateIntegrationBody) ApiOrganizationsUpdateIntegrationRequest { @@ -1710,29 +1697,28 @@ OrganizationsUpdateIntegration Update integration Updates the configuration for an organization integration - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @param integrationId - @return ApiOrganizationsUpdateIntegrationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @param integrationId + @return ApiOrganizationsUpdateIntegrationRequest */ func (a *OrganizationAPIService) OrganizationsUpdateIntegration(ctx context.Context, id string, integrationId string) ApiOrganizationsUpdateIntegrationRequest { return ApiOrganizationsUpdateIntegrationRequest{ - ApiService: a, - ctx: ctx, - id: id, + ApiService: a, + ctx: ctx, + id: id, integrationId: integrationId, } } // Execute executes the request -// -// @return OrganizationsUpdateIntegrationResponse +// @return OrganizationsUpdateIntegrationResponse func (a *OrganizationAPIService) OrganizationsUpdateIntegrationExecute(r ApiOrganizationsUpdateIntegrationRequest) (*OrganizationsUpdateIntegrationResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsUpdateIntegrationResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsUpdateIntegrationResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsUpdateIntegration") @@ -1792,14 +1778,14 @@ func (a *OrganizationAPIService) OrganizationsUpdateIntegrationExecute(r ApiOrga body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1816,10 +1802,10 @@ func (a *OrganizationAPIService) OrganizationsUpdateIntegrationExecute(r ApiOrga } type ApiOrganizationsUpdateInviteLinkRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string - body *OrganizationsUpdateInviteLinkBody + id string + body *OrganizationsUpdateInviteLinkBody } func (r ApiOrganizationsUpdateInviteLinkRequest) Body(body OrganizationsUpdateInviteLinkBody) ApiOrganizationsUpdateInviteLinkRequest { @@ -1836,27 +1822,26 @@ OrganizationsUpdateInviteLink Update an organization invite link Enables or disables the invite link for an organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsUpdateInviteLinkRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsUpdateInviteLinkRequest */ func (a *OrganizationAPIService) OrganizationsUpdateInviteLink(ctx context.Context, id string) ApiOrganizationsUpdateInviteLinkRequest { return ApiOrganizationsUpdateInviteLinkRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsUpdateInviteLinkResponse +// @return OrganizationsUpdateInviteLinkResponse func (a *OrganizationAPIService) OrganizationsUpdateInviteLinkExecute(r ApiOrganizationsUpdateInviteLinkRequest) (*OrganizationsUpdateInviteLinkResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsUpdateInviteLinkResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsUpdateInviteLinkResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsUpdateInviteLink") @@ -1915,14 +1900,14 @@ func (a *OrganizationAPIService) OrganizationsUpdateInviteLinkExecute(r ApiOrgan body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -1939,10 +1924,10 @@ func (a *OrganizationAPIService) OrganizationsUpdateInviteLinkExecute(r ApiOrgan } type ApiOrganizationsUpdateOrganizationRequest struct { - ctx context.Context + ctx context.Context ApiService *OrganizationAPIService - id string - body *OrganizationsUpdateOrganizationBody + id string + body *OrganizationsUpdateOrganizationBody } func (r ApiOrganizationsUpdateOrganizationRequest) Body(body OrganizationsUpdateOrganizationBody) ApiOrganizationsUpdateOrganizationRequest { @@ -1959,27 +1944,26 @@ OrganizationsUpdateOrganization Update an organization Updates the specified organization (can be referenced by ID or name) - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiOrganizationsUpdateOrganizationRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiOrganizationsUpdateOrganizationRequest */ func (a *OrganizationAPIService) OrganizationsUpdateOrganization(ctx context.Context, id string) ApiOrganizationsUpdateOrganizationRequest { return ApiOrganizationsUpdateOrganizationRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return OrganizationsUpdateOrganizationResponse +// @return OrganizationsUpdateOrganizationResponse func (a *OrganizationAPIService) OrganizationsUpdateOrganizationExecute(r ApiOrganizationsUpdateOrganizationRequest) (*OrganizationsUpdateOrganizationResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *OrganizationsUpdateOrganizationResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *OrganizationsUpdateOrganizationResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "OrganizationAPIService.OrganizationsUpdateOrganization") @@ -2038,14 +2022,14 @@ func (a *OrganizationAPIService) OrganizationsUpdateOrganizationExecute(r ApiOrg body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_roles.go b/pkg/openapi_client/api_roles.go index d879cf949c..ec377daf58 100644 --- a/pkg/openapi_client/api_roles.go +++ b/pkg/openapi_client/api_roles.go @@ -20,14 +20,15 @@ import ( "strings" ) + // RolesAPIService RolesAPI service type RolesAPIService service type ApiRolesAssignRoleRequest struct { - ctx context.Context + ctx context.Context ApiService *RolesAPIService - roleName string - body *RolesAssignRoleBody + roleName string + body *RolesAssignRoleBody } func (r ApiRolesAssignRoleRequest) Body(body RolesAssignRoleBody) ApiRolesAssignRoleRequest { @@ -44,27 +45,26 @@ RolesAssignRole Assign role Assigns a role to a user within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param roleName - @return ApiRolesAssignRoleRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param roleName + @return ApiRolesAssignRoleRequest */ func (a *RolesAPIService) RolesAssignRole(ctx context.Context, roleName string) ApiRolesAssignRoleRequest { return ApiRolesAssignRoleRequest{ ApiService: a, - ctx: ctx, - roleName: roleName, + ctx: ctx, + roleName: roleName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *RolesAPIService) RolesAssignRoleExecute(r ApiRolesAssignRoleRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RolesAPIService.RolesAssignRole") @@ -123,14 +123,14 @@ func (a *RolesAPIService) RolesAssignRoleExecute(r ApiRolesAssignRoleRequest) (m body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -147,9 +147,9 @@ func (a *RolesAPIService) RolesAssignRoleExecute(r ApiRolesAssignRoleRequest) (m } type ApiRolesCreateRoleRequest struct { - ctx context.Context + ctx context.Context ApiService *RolesAPIService - body *RolesCreateRoleRequest + body *RolesCreateRoleRequest } func (r ApiRolesCreateRoleRequest) Body(body RolesCreateRoleRequest) ApiRolesCreateRoleRequest { @@ -166,25 +166,24 @@ RolesCreateRole Create role Creates a new custom role with specified permissions - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiRolesCreateRoleRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiRolesCreateRoleRequest */ func (a *RolesAPIService) RolesCreateRole(ctx context.Context) ApiRolesCreateRoleRequest { return ApiRolesCreateRoleRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return RolesCreateRoleResponse +// @return RolesCreateRoleResponse func (a *RolesAPIService) RolesCreateRoleExecute(r ApiRolesCreateRoleRequest) (*RolesCreateRoleResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *RolesCreateRoleResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RolesCreateRoleResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RolesAPIService.RolesCreateRole") @@ -242,14 +241,14 @@ func (a *RolesAPIService) RolesCreateRoleExecute(r ApiRolesCreateRoleRequest) (* body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -266,11 +265,11 @@ func (a *RolesAPIService) RolesCreateRoleExecute(r ApiRolesCreateRoleRequest) (* } type ApiRolesDeleteRoleRequest struct { - ctx context.Context + ctx context.Context ApiService *RolesAPIService - roleName string + roleName string domainType *string - domainId *string + domainId *string } func (r ApiRolesDeleteRoleRequest) DomainType(domainType string) ApiRolesDeleteRoleRequest { @@ -292,27 +291,26 @@ RolesDeleteRole Delete role Deletes an existing custom role - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param roleName - @return ApiRolesDeleteRoleRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param roleName + @return ApiRolesDeleteRoleRequest */ func (a *RolesAPIService) RolesDeleteRole(ctx context.Context, roleName string) ApiRolesDeleteRoleRequest { return ApiRolesDeleteRoleRequest{ ApiService: a, - ctx: ctx, - roleName: roleName, + ctx: ctx, + roleName: roleName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *RolesAPIService) RolesDeleteRoleExecute(r ApiRolesDeleteRoleRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RolesAPIService.RolesDeleteRole") @@ -375,14 +373,14 @@ func (a *RolesAPIService) RolesDeleteRoleExecute(r ApiRolesDeleteRoleRequest) (m body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -399,11 +397,11 @@ func (a *RolesAPIService) RolesDeleteRoleExecute(r ApiRolesDeleteRoleRequest) (m } type ApiRolesDescribeRoleRequest struct { - ctx context.Context + ctx context.Context ApiService *RolesAPIService - roleName string + roleName string domainType *string - domainId *string + domainId *string } func (r ApiRolesDescribeRoleRequest) DomainType(domainType string) ApiRolesDescribeRoleRequest { @@ -425,27 +423,26 @@ RolesDescribeRole Describe role Returns detailed information about a specific role including permissions and inheritance - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param roleName - @return ApiRolesDescribeRoleRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param roleName + @return ApiRolesDescribeRoleRequest */ func (a *RolesAPIService) RolesDescribeRole(ctx context.Context, roleName string) ApiRolesDescribeRoleRequest { return ApiRolesDescribeRoleRequest{ ApiService: a, - ctx: ctx, - roleName: roleName, + ctx: ctx, + roleName: roleName, } } // Execute executes the request -// -// @return RolesDescribeRoleResponse +// @return RolesDescribeRoleResponse func (a *RolesAPIService) RolesDescribeRoleExecute(r ApiRolesDescribeRoleRequest) (*RolesDescribeRoleResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *RolesDescribeRoleResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RolesDescribeRoleResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RolesAPIService.RolesDescribeRole") @@ -508,14 +505,14 @@ func (a *RolesAPIService) RolesDescribeRoleExecute(r ApiRolesDescribeRoleRequest body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -532,10 +529,10 @@ func (a *RolesAPIService) RolesDescribeRoleExecute(r ApiRolesDescribeRoleRequest } type ApiRolesListRolesRequest struct { - ctx context.Context + ctx context.Context ApiService *RolesAPIService domainType *string - domainId *string + domainId *string } func (r ApiRolesListRolesRequest) DomainType(domainType string) ApiRolesListRolesRequest { @@ -557,25 +554,24 @@ RolesListRoles List roles Returns available roles for a specific domain type with their permissions and inheritance - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiRolesListRolesRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiRolesListRolesRequest */ func (a *RolesAPIService) RolesListRoles(ctx context.Context) ApiRolesListRolesRequest { return ApiRolesListRolesRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return RolesListRolesResponse +// @return RolesListRolesResponse func (a *RolesAPIService) RolesListRolesExecute(r ApiRolesListRolesRequest) (*RolesListRolesResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *RolesListRolesResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RolesListRolesResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RolesAPIService.RolesListRoles") @@ -637,14 +633,14 @@ func (a *RolesAPIService) RolesListRolesExecute(r ApiRolesListRolesRequest) (*Ro body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -661,10 +657,10 @@ func (a *RolesAPIService) RolesListRolesExecute(r ApiRolesListRolesRequest) (*Ro } type ApiRolesUpdateRoleRequest struct { - ctx context.Context + ctx context.Context ApiService *RolesAPIService - roleName string - body *RolesUpdateRoleBody + roleName string + body *RolesUpdateRoleBody } func (r ApiRolesUpdateRoleRequest) Body(body RolesUpdateRoleBody) ApiRolesUpdateRoleRequest { @@ -681,27 +677,26 @@ RolesUpdateRole Update role Updates an existing custom role with new permissions - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param roleName - @return ApiRolesUpdateRoleRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param roleName + @return ApiRolesUpdateRoleRequest */ func (a *RolesAPIService) RolesUpdateRole(ctx context.Context, roleName string) ApiRolesUpdateRoleRequest { return ApiRolesUpdateRoleRequest{ ApiService: a, - ctx: ctx, - roleName: roleName, + ctx: ctx, + roleName: roleName, } } // Execute executes the request -// -// @return RolesUpdateRoleResponse +// @return RolesUpdateRoleResponse func (a *RolesAPIService) RolesUpdateRoleExecute(r ApiRolesUpdateRoleRequest) (*RolesUpdateRoleResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *RolesUpdateRoleResponse + localVarHTTPMethod = http.MethodPut + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RolesUpdateRoleResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RolesAPIService.RolesUpdateRole") @@ -760,14 +755,14 @@ func (a *RolesAPIService) RolesUpdateRoleExecute(r ApiRolesUpdateRoleRequest) (* body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_script.go b/pkg/openapi_client/api_script.go new file mode 100644 index 0000000000..1bfb33d33b --- /dev/null +++ b/pkg/openapi_client/api_script.go @@ -0,0 +1,716 @@ +/* +Superplane Organizations API + +API for managing organizations in the Superplane service + +API version: 1.0 +Contact: support@superplane.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi_client + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + + +// ScriptAPIService ScriptAPI service +type ScriptAPIService service + +type ApiScriptsCreateScriptRequest struct { + ctx context.Context + ApiService *ScriptAPIService + body *ScriptsCreateScriptRequest +} + +func (r ApiScriptsCreateScriptRequest) Body(body ScriptsCreateScriptRequest) ApiScriptsCreateScriptRequest { + r.body = &body + return r +} + +func (r ApiScriptsCreateScriptRequest) Execute() (*ScriptsCreateScriptResponse, *http.Response, error) { + return r.ApiService.ScriptsCreateScriptExecute(r) +} + +/* +ScriptsCreateScript Create script + +Creates a new in-app script + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiScriptsCreateScriptRequest +*/ +func (a *ScriptAPIService) ScriptsCreateScript(ctx context.Context) ApiScriptsCreateScriptRequest { + return ApiScriptsCreateScriptRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// @return ScriptsCreateScriptResponse +func (a *ScriptAPIService) ScriptsCreateScriptExecute(r ApiScriptsCreateScriptRequest) (*ScriptsCreateScriptResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ScriptsCreateScriptResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ScriptAPIService.ScriptsCreateScript") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/v1/scripts" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiScriptsDeleteScriptRequest struct { + ctx context.Context + ApiService *ScriptAPIService + id string +} + +func (r ApiScriptsDeleteScriptRequest) Execute() (map[string]interface{}, *http.Response, error) { + return r.ApiService.ScriptsDeleteScriptExecute(r) +} + +/* +ScriptsDeleteScript Delete script + +Deletes an existing script + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiScriptsDeleteScriptRequest +*/ +func (a *ScriptAPIService) ScriptsDeleteScript(ctx context.Context, id string) ApiScriptsDeleteScriptRequest { + return ApiScriptsDeleteScriptRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// @return map[string]interface{} +func (a *ScriptAPIService) ScriptsDeleteScriptExecute(r ApiScriptsDeleteScriptRequest) (map[string]interface{}, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ScriptAPIService.ScriptsDeleteScript") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/v1/scripts/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiScriptsDescribeScriptRequest struct { + ctx context.Context + ApiService *ScriptAPIService + id string +} + +func (r ApiScriptsDescribeScriptRequest) Execute() (*ScriptsDescribeScriptResponse, *http.Response, error) { + return r.ApiService.ScriptsDescribeScriptExecute(r) +} + +/* +ScriptsDescribeScript Describe script + +Returns a script + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiScriptsDescribeScriptRequest +*/ +func (a *ScriptAPIService) ScriptsDescribeScript(ctx context.Context, id string) ApiScriptsDescribeScriptRequest { + return ApiScriptsDescribeScriptRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// @return ScriptsDescribeScriptResponse +func (a *ScriptAPIService) ScriptsDescribeScriptExecute(r ApiScriptsDescribeScriptRequest) (*ScriptsDescribeScriptResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ScriptsDescribeScriptResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ScriptAPIService.ScriptsDescribeScript") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/v1/scripts/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiScriptsGenerateScriptRequest struct { + ctx context.Context + ApiService *ScriptAPIService + scriptId string + body *ScriptsGenerateScriptBody +} + +func (r ApiScriptsGenerateScriptRequest) Body(body ScriptsGenerateScriptBody) ApiScriptsGenerateScriptRequest { + r.body = &body + return r +} + +func (r ApiScriptsGenerateScriptRequest) Execute() (*ScriptsGenerateScriptResponse, *http.Response, error) { + return r.ApiService.ScriptsGenerateScriptExecute(r) +} + +/* +ScriptsGenerateScript Generate script + +Uses AI to generate or update script code based on a user prompt + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param scriptId + @return ApiScriptsGenerateScriptRequest +*/ +func (a *ScriptAPIService) ScriptsGenerateScript(ctx context.Context, scriptId string) ApiScriptsGenerateScriptRequest { + return ApiScriptsGenerateScriptRequest{ + ApiService: a, + ctx: ctx, + scriptId: scriptId, + } +} + +// Execute executes the request +// @return ScriptsGenerateScriptResponse +func (a *ScriptAPIService) ScriptsGenerateScriptExecute(r ApiScriptsGenerateScriptRequest) (*ScriptsGenerateScriptResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ScriptsGenerateScriptResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ScriptAPIService.ScriptsGenerateScript") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/v1/scripts/{scriptId}/generate" + localVarPath = strings.Replace(localVarPath, "{"+"scriptId"+"}", url.PathEscape(parameterValueToString(r.scriptId, "scriptId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiScriptsListScriptsRequest struct { + ctx context.Context + ApiService *ScriptAPIService +} + +func (r ApiScriptsListScriptsRequest) Execute() (*ScriptsListScriptsResponse, *http.Response, error) { + return r.ApiService.ScriptsListScriptsExecute(r) +} + +/* +ScriptsListScripts List scripts + +Returns a list of all scripts in the organization + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiScriptsListScriptsRequest +*/ +func (a *ScriptAPIService) ScriptsListScripts(ctx context.Context) ApiScriptsListScriptsRequest { + return ApiScriptsListScriptsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// @return ScriptsListScriptsResponse +func (a *ScriptAPIService) ScriptsListScriptsExecute(r ApiScriptsListScriptsRequest) (*ScriptsListScriptsResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ScriptsListScriptsResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ScriptAPIService.ScriptsListScripts") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/v1/scripts" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiScriptsUpdateScriptRequest struct { + ctx context.Context + ApiService *ScriptAPIService + id string + body *ScriptsUpdateScriptBody +} + +func (r ApiScriptsUpdateScriptRequest) Body(body ScriptsUpdateScriptBody) ApiScriptsUpdateScriptRequest { + r.body = &body + return r +} + +func (r ApiScriptsUpdateScriptRequest) Execute() (*ScriptsUpdateScriptResponse, *http.Response, error) { + return r.ApiService.ScriptsUpdateScriptExecute(r) +} + +/* +ScriptsUpdateScript Update script + +Updates an existing script + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiScriptsUpdateScriptRequest +*/ +func (a *ScriptAPIService) ScriptsUpdateScript(ctx context.Context, id string) ApiScriptsUpdateScriptRequest { + return ApiScriptsUpdateScriptRequest{ + ApiService: a, + ctx: ctx, + id: id, + } +} + +// Execute executes the request +// @return ScriptsUpdateScriptResponse +func (a *ScriptAPIService) ScriptsUpdateScriptExecute(r ApiScriptsUpdateScriptRequest) (*ScriptsUpdateScriptResponse, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ScriptsUpdateScriptResponse + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ScriptAPIService.ScriptsUpdateScript") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/v1/scripts/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", url.PathEscape(parameterValueToString(r.id, "id")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/pkg/openapi_client/api_secret.go b/pkg/openapi_client/api_secret.go index 8c5aa45e38..6edc05749f 100644 --- a/pkg/openapi_client/api_secret.go +++ b/pkg/openapi_client/api_secret.go @@ -20,13 +20,14 @@ import ( "strings" ) + // SecretAPIService SecretAPI service type SecretAPIService service type ApiSecretsCreateSecretRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - body *SecretsCreateSecretRequest + body *SecretsCreateSecretRequest } func (r ApiSecretsCreateSecretRequest) Body(body SecretsCreateSecretRequest) ApiSecretsCreateSecretRequest { @@ -43,25 +44,24 @@ SecretsCreateSecret Create a new secret Creates a new secret - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSecretsCreateSecretRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiSecretsCreateSecretRequest */ func (a *SecretAPIService) SecretsCreateSecret(ctx context.Context) ApiSecretsCreateSecretRequest { return ApiSecretsCreateSecretRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return SecretsCreateSecretResponse +// @return SecretsCreateSecretResponse func (a *SecretAPIService) SecretsCreateSecretExecute(r ApiSecretsCreateSecretRequest) (*SecretsCreateSecretResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsCreateSecretResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsCreateSecretResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsCreateSecret") @@ -119,14 +119,14 @@ func (a *SecretAPIService) SecretsCreateSecretExecute(r ApiSecretsCreateSecretRe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -143,11 +143,11 @@ func (a *SecretAPIService) SecretsCreateSecretExecute(r ApiSecretsCreateSecretRe } type ApiSecretsDeleteSecretRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - idOrName string + idOrName string domainType *string - domainId *string + domainId *string } func (r ApiSecretsDeleteSecretRequest) DomainType(domainType string) ApiSecretsDeleteSecretRequest { @@ -169,27 +169,26 @@ SecretsDeleteSecret Deletes a secret Deletes the specified secret - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param idOrName - @return ApiSecretsDeleteSecretRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param idOrName + @return ApiSecretsDeleteSecretRequest */ func (a *SecretAPIService) SecretsDeleteSecret(ctx context.Context, idOrName string) ApiSecretsDeleteSecretRequest { return ApiSecretsDeleteSecretRequest{ ApiService: a, - ctx: ctx, - idOrName: idOrName, + ctx: ctx, + idOrName: idOrName, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *SecretAPIService) SecretsDeleteSecretExecute(r ApiSecretsDeleteSecretRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsDeleteSecret") @@ -252,14 +251,14 @@ func (a *SecretAPIService) SecretsDeleteSecretExecute(r ApiSecretsDeleteSecretRe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -276,12 +275,12 @@ func (a *SecretAPIService) SecretsDeleteSecretExecute(r ApiSecretsDeleteSecretRe } type ApiSecretsDeleteSecretKeyRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - idOrName string - keyName string + idOrName string + keyName string domainType *string - domainId *string + domainId *string } func (r ApiSecretsDeleteSecretKeyRequest) DomainType(domainType string) ApiSecretsDeleteSecretKeyRequest { @@ -303,29 +302,28 @@ SecretsDeleteSecretKey Remove a key from a secret Removes one key from the secret. Secret must have at least one key remaining. - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param idOrName - @param keyName - @return ApiSecretsDeleteSecretKeyRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param idOrName + @param keyName + @return ApiSecretsDeleteSecretKeyRequest */ func (a *SecretAPIService) SecretsDeleteSecretKey(ctx context.Context, idOrName string, keyName string) ApiSecretsDeleteSecretKeyRequest { return ApiSecretsDeleteSecretKeyRequest{ ApiService: a, - ctx: ctx, - idOrName: idOrName, - keyName: keyName, + ctx: ctx, + idOrName: idOrName, + keyName: keyName, } } // Execute executes the request -// -// @return SecretsDeleteSecretKeyResponse +// @return SecretsDeleteSecretKeyResponse func (a *SecretAPIService) SecretsDeleteSecretKeyExecute(r ApiSecretsDeleteSecretKeyRequest) (*SecretsDeleteSecretKeyResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsDeleteSecretKeyResponse + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsDeleteSecretKeyResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsDeleteSecretKey") @@ -389,14 +387,14 @@ func (a *SecretAPIService) SecretsDeleteSecretKeyExecute(r ApiSecretsDeleteSecre body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -413,11 +411,11 @@ func (a *SecretAPIService) SecretsDeleteSecretKeyExecute(r ApiSecretsDeleteSecre } type ApiSecretsDescribeSecretRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - idOrName string + idOrName string domainType *string - domainId *string + domainId *string } func (r ApiSecretsDescribeSecretRequest) DomainType(domainType string) ApiSecretsDescribeSecretRequest { @@ -439,27 +437,26 @@ SecretsDescribeSecret Get secret details Returns the details of a specific secret - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param idOrName - @return ApiSecretsDescribeSecretRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param idOrName + @return ApiSecretsDescribeSecretRequest */ func (a *SecretAPIService) SecretsDescribeSecret(ctx context.Context, idOrName string) ApiSecretsDescribeSecretRequest { return ApiSecretsDescribeSecretRequest{ ApiService: a, - ctx: ctx, - idOrName: idOrName, + ctx: ctx, + idOrName: idOrName, } } // Execute executes the request -// -// @return SecretsDescribeSecretResponse +// @return SecretsDescribeSecretResponse func (a *SecretAPIService) SecretsDescribeSecretExecute(r ApiSecretsDescribeSecretRequest) (*SecretsDescribeSecretResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsDescribeSecretResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsDescribeSecretResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsDescribeSecret") @@ -522,14 +519,14 @@ func (a *SecretAPIService) SecretsDescribeSecretExecute(r ApiSecretsDescribeSecr body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -546,10 +543,10 @@ func (a *SecretAPIService) SecretsDescribeSecretExecute(r ApiSecretsDescribeSecr } type ApiSecretsListSecretsRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService domainType *string - domainId *string + domainId *string } func (r ApiSecretsListSecretsRequest) DomainType(domainType string) ApiSecretsListSecretsRequest { @@ -571,25 +568,24 @@ SecretsListSecrets List secrets Returns the list of secrets - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSecretsListSecretsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiSecretsListSecretsRequest */ func (a *SecretAPIService) SecretsListSecrets(ctx context.Context) ApiSecretsListSecretsRequest { return ApiSecretsListSecretsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return SecretsListSecretsResponse +// @return SecretsListSecretsResponse func (a *SecretAPIService) SecretsListSecretsExecute(r ApiSecretsListSecretsRequest) (*SecretsListSecretsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsListSecretsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsListSecretsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsListSecrets") @@ -651,14 +647,14 @@ func (a *SecretAPIService) SecretsListSecretsExecute(r ApiSecretsListSecretsRequ body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -675,11 +671,11 @@ func (a *SecretAPIService) SecretsListSecretsExecute(r ApiSecretsListSecretsRequ } type ApiSecretsSetSecretKeyRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - idOrName string - keyName string - body *SecretsSetSecretKeyBody + idOrName string + keyName string + body *SecretsSetSecretKeyBody } func (r ApiSecretsSetSecretKeyRequest) Body(body SecretsSetSecretKeyBody) ApiSecretsSetSecretKeyRequest { @@ -696,29 +692,28 @@ SecretsSetSecretKey Set or overwrite a single key in a secret Sets the value for one key. Creates the key if missing, overwrites if present. - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param idOrName - @param keyName - @return ApiSecretsSetSecretKeyRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param idOrName + @param keyName + @return ApiSecretsSetSecretKeyRequest */ func (a *SecretAPIService) SecretsSetSecretKey(ctx context.Context, idOrName string, keyName string) ApiSecretsSetSecretKeyRequest { return ApiSecretsSetSecretKeyRequest{ ApiService: a, - ctx: ctx, - idOrName: idOrName, - keyName: keyName, + ctx: ctx, + idOrName: idOrName, + keyName: keyName, } } // Execute executes the request -// -// @return SecretsSetSecretKeyResponse +// @return SecretsSetSecretKeyResponse func (a *SecretAPIService) SecretsSetSecretKeyExecute(r ApiSecretsSetSecretKeyRequest) (*SecretsSetSecretKeyResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsSetSecretKeyResponse + localVarHTTPMethod = http.MethodPut + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsSetSecretKeyResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsSetSecretKey") @@ -778,14 +773,14 @@ func (a *SecretAPIService) SecretsSetSecretKeyExecute(r ApiSecretsSetSecretKeyRe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -802,10 +797,10 @@ func (a *SecretAPIService) SecretsSetSecretKeyExecute(r ApiSecretsSetSecretKeyRe } type ApiSecretsUpdateSecretRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - idOrName string - body *SecretsUpdateSecretBody + idOrName string + body *SecretsUpdateSecretBody } func (r ApiSecretsUpdateSecretRequest) Body(body SecretsUpdateSecretBody) ApiSecretsUpdateSecretRequest { @@ -822,27 +817,26 @@ SecretsUpdateSecret Updates a secret Updates the specified secret - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param idOrName - @return ApiSecretsUpdateSecretRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param idOrName + @return ApiSecretsUpdateSecretRequest */ func (a *SecretAPIService) SecretsUpdateSecret(ctx context.Context, idOrName string) ApiSecretsUpdateSecretRequest { return ApiSecretsUpdateSecretRequest{ ApiService: a, - ctx: ctx, - idOrName: idOrName, + ctx: ctx, + idOrName: idOrName, } } // Execute executes the request -// -// @return SecretsUpdateSecretResponse +// @return SecretsUpdateSecretResponse func (a *SecretAPIService) SecretsUpdateSecretExecute(r ApiSecretsUpdateSecretRequest) (*SecretsUpdateSecretResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsUpdateSecretResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsUpdateSecretResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsUpdateSecret") @@ -901,14 +895,14 @@ func (a *SecretAPIService) SecretsUpdateSecretExecute(r ApiSecretsUpdateSecretRe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -925,10 +919,10 @@ func (a *SecretAPIService) SecretsUpdateSecretExecute(r ApiSecretsUpdateSecretRe } type ApiSecretsUpdateSecretNameRequest struct { - ctx context.Context + ctx context.Context ApiService *SecretAPIService - idOrName string - body *SecretsUpdateSecretNameBody + idOrName string + body *SecretsUpdateSecretNameBody } func (r ApiSecretsUpdateSecretNameRequest) Body(body SecretsUpdateSecretNameBody) ApiSecretsUpdateSecretNameRequest { @@ -945,27 +939,26 @@ SecretsUpdateSecretName Update secret name Updates only the name of the secret. Name must be unique within the domain. - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param idOrName - @return ApiSecretsUpdateSecretNameRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param idOrName + @return ApiSecretsUpdateSecretNameRequest */ func (a *SecretAPIService) SecretsUpdateSecretName(ctx context.Context, idOrName string) ApiSecretsUpdateSecretNameRequest { return ApiSecretsUpdateSecretNameRequest{ ApiService: a, - ctx: ctx, - idOrName: idOrName, + ctx: ctx, + idOrName: idOrName, } } // Execute executes the request -// -// @return SecretsUpdateSecretNameResponse +// @return SecretsUpdateSecretNameResponse func (a *SecretAPIService) SecretsUpdateSecretNameExecute(r ApiSecretsUpdateSecretNameRequest) (*SecretsUpdateSecretNameResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *SecretsUpdateSecretNameResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *SecretsUpdateSecretNameResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "SecretAPIService.SecretsUpdateSecretName") @@ -1024,14 +1017,14 @@ func (a *SecretAPIService) SecretsUpdateSecretNameExecute(r ApiSecretsUpdateSecr body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_service_accounts.go b/pkg/openapi_client/api_service_accounts.go index 9e4b13259c..1cb34019ec 100644 --- a/pkg/openapi_client/api_service_accounts.go +++ b/pkg/openapi_client/api_service_accounts.go @@ -20,13 +20,14 @@ import ( "strings" ) + // ServiceAccountsAPIService ServiceAccountsAPI service type ServiceAccountsAPIService service type ApiServiceAccountsCreateServiceAccountRequest struct { - ctx context.Context + ctx context.Context ApiService *ServiceAccountsAPIService - body *ServiceAccountsCreateServiceAccountRequest + body *ServiceAccountsCreateServiceAccountRequest } func (r ApiServiceAccountsCreateServiceAccountRequest) Body(body ServiceAccountsCreateServiceAccountRequest) ApiServiceAccountsCreateServiceAccountRequest { @@ -43,25 +44,24 @@ ServiceAccountsCreateServiceAccount Create a service account Creates a new service account in the organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiServiceAccountsCreateServiceAccountRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiServiceAccountsCreateServiceAccountRequest */ func (a *ServiceAccountsAPIService) ServiceAccountsCreateServiceAccount(ctx context.Context) ApiServiceAccountsCreateServiceAccountRequest { return ApiServiceAccountsCreateServiceAccountRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return ServiceAccountsCreateServiceAccountResponse +// @return ServiceAccountsCreateServiceAccountResponse func (a *ServiceAccountsAPIService) ServiceAccountsCreateServiceAccountExecute(r ApiServiceAccountsCreateServiceAccountRequest) (*ServiceAccountsCreateServiceAccountResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ServiceAccountsCreateServiceAccountResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServiceAccountsCreateServiceAccountResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServiceAccountsAPIService.ServiceAccountsCreateServiceAccount") @@ -119,14 +119,14 @@ func (a *ServiceAccountsAPIService) ServiceAccountsCreateServiceAccountExecute(r body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -143,9 +143,9 @@ func (a *ServiceAccountsAPIService) ServiceAccountsCreateServiceAccountExecute(r } type ApiServiceAccountsDeleteServiceAccountRequest struct { - ctx context.Context + ctx context.Context ApiService *ServiceAccountsAPIService - id string + id string } func (r ApiServiceAccountsDeleteServiceAccountRequest) Execute() (map[string]interface{}, *http.Response, error) { @@ -157,27 +157,26 @@ ServiceAccountsDeleteServiceAccount Delete a service account Deletes a service account and removes its RBAC policies - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiServiceAccountsDeleteServiceAccountRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiServiceAccountsDeleteServiceAccountRequest */ func (a *ServiceAccountsAPIService) ServiceAccountsDeleteServiceAccount(ctx context.Context, id string) ApiServiceAccountsDeleteServiceAccountRequest { return ApiServiceAccountsDeleteServiceAccountRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return map[string]interface{} +// @return map[string]interface{} func (a *ServiceAccountsAPIService) ServiceAccountsDeleteServiceAccountExecute(r ApiServiceAccountsDeleteServiceAccountRequest) (map[string]interface{}, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue map[string]interface{} + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue map[string]interface{} ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServiceAccountsAPIService.ServiceAccountsDeleteServiceAccount") @@ -231,14 +230,14 @@ func (a *ServiceAccountsAPIService) ServiceAccountsDeleteServiceAccountExecute(r body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -255,9 +254,9 @@ func (a *ServiceAccountsAPIService) ServiceAccountsDeleteServiceAccountExecute(r } type ApiServiceAccountsDescribeServiceAccountRequest struct { - ctx context.Context + ctx context.Context ApiService *ServiceAccountsAPIService - id string + id string } func (r ApiServiceAccountsDescribeServiceAccountRequest) Execute() (*ServiceAccountsDescribeServiceAccountResponse, *http.Response, error) { @@ -269,27 +268,26 @@ ServiceAccountsDescribeServiceAccount Describe a service account Returns details of a specific service account - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiServiceAccountsDescribeServiceAccountRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiServiceAccountsDescribeServiceAccountRequest */ func (a *ServiceAccountsAPIService) ServiceAccountsDescribeServiceAccount(ctx context.Context, id string) ApiServiceAccountsDescribeServiceAccountRequest { return ApiServiceAccountsDescribeServiceAccountRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return ServiceAccountsDescribeServiceAccountResponse +// @return ServiceAccountsDescribeServiceAccountResponse func (a *ServiceAccountsAPIService) ServiceAccountsDescribeServiceAccountExecute(r ApiServiceAccountsDescribeServiceAccountRequest) (*ServiceAccountsDescribeServiceAccountResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ServiceAccountsDescribeServiceAccountResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServiceAccountsDescribeServiceAccountResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServiceAccountsAPIService.ServiceAccountsDescribeServiceAccount") @@ -343,14 +341,14 @@ func (a *ServiceAccountsAPIService) ServiceAccountsDescribeServiceAccountExecute body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -367,7 +365,7 @@ func (a *ServiceAccountsAPIService) ServiceAccountsDescribeServiceAccountExecute } type ApiServiceAccountsListServiceAccountsRequest struct { - ctx context.Context + ctx context.Context ApiService *ServiceAccountsAPIService } @@ -380,25 +378,24 @@ ServiceAccountsListServiceAccounts List service accounts Returns all service accounts in the organization - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiServiceAccountsListServiceAccountsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiServiceAccountsListServiceAccountsRequest */ func (a *ServiceAccountsAPIService) ServiceAccountsListServiceAccounts(ctx context.Context) ApiServiceAccountsListServiceAccountsRequest { return ApiServiceAccountsListServiceAccountsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return ServiceAccountsListServiceAccountsResponse +// @return ServiceAccountsListServiceAccountsResponse func (a *ServiceAccountsAPIService) ServiceAccountsListServiceAccountsExecute(r ApiServiceAccountsListServiceAccountsRequest) (*ServiceAccountsListServiceAccountsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ServiceAccountsListServiceAccountsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServiceAccountsListServiceAccountsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServiceAccountsAPIService.ServiceAccountsListServiceAccounts") @@ -451,14 +448,14 @@ func (a *ServiceAccountsAPIService) ServiceAccountsListServiceAccountsExecute(r body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -475,10 +472,10 @@ func (a *ServiceAccountsAPIService) ServiceAccountsListServiceAccountsExecute(r } type ApiServiceAccountsRegenerateServiceAccountTokenRequest struct { - ctx context.Context + ctx context.Context ApiService *ServiceAccountsAPIService - id string - body *map[string]interface{} + id string + body *map[string]interface{} } func (r ApiServiceAccountsRegenerateServiceAccountTokenRequest) Body(body map[string]interface{}) ApiServiceAccountsRegenerateServiceAccountTokenRequest { @@ -495,27 +492,26 @@ ServiceAccountsRegenerateServiceAccountToken Regenerate service account token Regenerates the API token for a service account - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiServiceAccountsRegenerateServiceAccountTokenRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiServiceAccountsRegenerateServiceAccountTokenRequest */ func (a *ServiceAccountsAPIService) ServiceAccountsRegenerateServiceAccountToken(ctx context.Context, id string) ApiServiceAccountsRegenerateServiceAccountTokenRequest { return ApiServiceAccountsRegenerateServiceAccountTokenRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return ServiceAccountsRegenerateServiceAccountTokenResponse +// @return ServiceAccountsRegenerateServiceAccountTokenResponse func (a *ServiceAccountsAPIService) ServiceAccountsRegenerateServiceAccountTokenExecute(r ApiServiceAccountsRegenerateServiceAccountTokenRequest) (*ServiceAccountsRegenerateServiceAccountTokenResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ServiceAccountsRegenerateServiceAccountTokenResponse + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServiceAccountsRegenerateServiceAccountTokenResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServiceAccountsAPIService.ServiceAccountsRegenerateServiceAccountToken") @@ -574,14 +570,14 @@ func (a *ServiceAccountsAPIService) ServiceAccountsRegenerateServiceAccountToken body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -598,10 +594,10 @@ func (a *ServiceAccountsAPIService) ServiceAccountsRegenerateServiceAccountToken } type ApiServiceAccountsUpdateServiceAccountRequest struct { - ctx context.Context + ctx context.Context ApiService *ServiceAccountsAPIService - id string - body *ServiceAccountsUpdateServiceAccountBody + id string + body *ServiceAccountsUpdateServiceAccountBody } func (r ApiServiceAccountsUpdateServiceAccountRequest) Body(body ServiceAccountsUpdateServiceAccountBody) ApiServiceAccountsUpdateServiceAccountRequest { @@ -618,27 +614,26 @@ ServiceAccountsUpdateServiceAccount Update a service account Updates the name or description of a service account - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param id - @return ApiServiceAccountsUpdateServiceAccountRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param id + @return ApiServiceAccountsUpdateServiceAccountRequest */ func (a *ServiceAccountsAPIService) ServiceAccountsUpdateServiceAccount(ctx context.Context, id string) ApiServiceAccountsUpdateServiceAccountRequest { return ApiServiceAccountsUpdateServiceAccountRequest{ ApiService: a, - ctx: ctx, - id: id, + ctx: ctx, + id: id, } } // Execute executes the request -// -// @return ServiceAccountsUpdateServiceAccountResponse +// @return ServiceAccountsUpdateServiceAccountResponse func (a *ServiceAccountsAPIService) ServiceAccountsUpdateServiceAccountExecute(r ApiServiceAccountsUpdateServiceAccountRequest) (*ServiceAccountsUpdateServiceAccountResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ServiceAccountsUpdateServiceAccountResponse + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServiceAccountsUpdateServiceAccountResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServiceAccountsAPIService.ServiceAccountsUpdateServiceAccount") @@ -697,14 +692,14 @@ func (a *ServiceAccountsAPIService) ServiceAccountsUpdateServiceAccountExecute(r body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_trigger.go b/pkg/openapi_client/api_trigger.go index 4164527ad4..af6e277e9b 100644 --- a/pkg/openapi_client/api_trigger.go +++ b/pkg/openapi_client/api_trigger.go @@ -20,13 +20,14 @@ import ( "strings" ) + // TriggerAPIService TriggerAPI service type TriggerAPIService service type ApiTriggersDescribeTriggerRequest struct { - ctx context.Context + ctx context.Context ApiService *TriggerAPIService - name string + name string } func (r ApiTriggersDescribeTriggerRequest) Execute() (*TriggersDescribeTriggerResponse, *http.Response, error) { @@ -38,27 +39,26 @@ TriggersDescribeTrigger Describe trigger Returns a trigger by its name - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param name - @return ApiTriggersDescribeTriggerRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param name + @return ApiTriggersDescribeTriggerRequest */ func (a *TriggerAPIService) TriggersDescribeTrigger(ctx context.Context, name string) ApiTriggersDescribeTriggerRequest { return ApiTriggersDescribeTriggerRequest{ ApiService: a, - ctx: ctx, - name: name, + ctx: ctx, + name: name, } } // Execute executes the request -// -// @return TriggersDescribeTriggerResponse +// @return TriggersDescribeTriggerResponse func (a *TriggerAPIService) TriggersDescribeTriggerExecute(r ApiTriggersDescribeTriggerRequest) (*TriggersDescribeTriggerResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *TriggersDescribeTriggerResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *TriggersDescribeTriggerResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TriggerAPIService.TriggersDescribeTrigger") @@ -112,14 +112,14 @@ func (a *TriggerAPIService) TriggersDescribeTriggerExecute(r ApiTriggersDescribe body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -136,7 +136,7 @@ func (a *TriggerAPIService) TriggersDescribeTriggerExecute(r ApiTriggersDescribe } type ApiTriggersListTriggersRequest struct { - ctx context.Context + ctx context.Context ApiService *TriggerAPIService } @@ -149,25 +149,24 @@ TriggersListTriggers List triggers Returns a list of all available triggers - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiTriggersListTriggersRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiTriggersListTriggersRequest */ func (a *TriggerAPIService) TriggersListTriggers(ctx context.Context) ApiTriggersListTriggersRequest { return ApiTriggersListTriggersRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return TriggersListTriggersResponse +// @return TriggersListTriggersResponse func (a *TriggerAPIService) TriggersListTriggersExecute(r ApiTriggersListTriggersRequest) (*TriggersListTriggersResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *TriggersListTriggersResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *TriggersListTriggersResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TriggerAPIService.TriggersListTriggers") @@ -220,14 +219,14 @@ func (a *TriggerAPIService) TriggersListTriggersExecute(r ApiTriggersListTrigger body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_users.go b/pkg/openapi_client/api_users.go index 23a4a13c1a..a6d71a6561 100644 --- a/pkg/openapi_client/api_users.go +++ b/pkg/openapi_client/api_users.go @@ -20,15 +20,16 @@ import ( "strings" ) + // UsersAPIService UsersAPI service type UsersAPIService service type ApiUsersListUserPermissionsRequest struct { - ctx context.Context + ctx context.Context ApiService *UsersAPIService - userId string + userId string domainType *string - domainId *string + domainId *string } func (r ApiUsersListUserPermissionsRequest) DomainType(domainType string) ApiUsersListUserPermissionsRequest { @@ -50,27 +51,26 @@ UsersListUserPermissions List user permissions Returns all permissions a user has within a specific domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param userId - @return ApiUsersListUserPermissionsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param userId + @return ApiUsersListUserPermissionsRequest */ func (a *UsersAPIService) UsersListUserPermissions(ctx context.Context, userId string) ApiUsersListUserPermissionsRequest { return ApiUsersListUserPermissionsRequest{ ApiService: a, - ctx: ctx, - userId: userId, + ctx: ctx, + userId: userId, } } // Execute executes the request -// -// @return UsersListUserPermissionsResponse +// @return UsersListUserPermissionsResponse func (a *UsersAPIService) UsersListUserPermissionsExecute(r ApiUsersListUserPermissionsRequest) (*UsersListUserPermissionsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *UsersListUserPermissionsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *UsersListUserPermissionsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "UsersAPIService.UsersListUserPermissions") @@ -133,14 +133,14 @@ func (a *UsersAPIService) UsersListUserPermissionsExecute(r ApiUsersListUserPerm body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -157,11 +157,11 @@ func (a *UsersAPIService) UsersListUserPermissionsExecute(r ApiUsersListUserPerm } type ApiUsersListUserRolesRequest struct { - ctx context.Context + ctx context.Context ApiService *UsersAPIService - userId string + userId string domainType *string - domainId *string + domainId *string } func (r ApiUsersListUserRolesRequest) DomainType(domainType string) ApiUsersListUserRolesRequest { @@ -183,27 +183,26 @@ UsersListUserRoles Get user roles Returns the roles a user has within a specific domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param userId - @return ApiUsersListUserRolesRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param userId + @return ApiUsersListUserRolesRequest */ func (a *UsersAPIService) UsersListUserRoles(ctx context.Context, userId string) ApiUsersListUserRolesRequest { return ApiUsersListUserRolesRequest{ ApiService: a, - ctx: ctx, - userId: userId, + ctx: ctx, + userId: userId, } } // Execute executes the request -// -// @return UsersListUserRolesResponse +// @return UsersListUserRolesResponse func (a *UsersAPIService) UsersListUserRolesExecute(r ApiUsersListUserRolesRequest) (*UsersListUserRolesResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *UsersListUserRolesResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *UsersListUserRolesResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "UsersAPIService.UsersListUserRoles") @@ -266,14 +265,14 @@ func (a *UsersAPIService) UsersListUserRolesExecute(r ApiUsersListUserRolesReque body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -290,10 +289,10 @@ func (a *UsersAPIService) UsersListUserRolesExecute(r ApiUsersListUserRolesReque } type ApiUsersListUsersRequest struct { - ctx context.Context - ApiService *UsersAPIService - domainType *string - domainId *string + ctx context.Context + ApiService *UsersAPIService + domainType *string + domainId *string includeServiceAccounts *bool } @@ -321,25 +320,24 @@ UsersListUsers List users Returns all users that have roles within a domain - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiUsersListUsersRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiUsersListUsersRequest */ func (a *UsersAPIService) UsersListUsers(ctx context.Context) ApiUsersListUsersRequest { return ApiUsersListUsersRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return UsersListUsersResponse +// @return UsersListUsersResponse func (a *UsersAPIService) UsersListUsersExecute(r ApiUsersListUsersRequest) (*UsersListUsersResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *UsersListUsersResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *UsersListUsersResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "UsersAPIService.UsersListUsers") @@ -404,14 +402,14 @@ func (a *UsersAPIService) UsersListUsersExecute(r ApiUsersListUsersRequest) (*Us body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/api_widget.go b/pkg/openapi_client/api_widget.go index 9fcf1966d3..bbbdebcf95 100644 --- a/pkg/openapi_client/api_widget.go +++ b/pkg/openapi_client/api_widget.go @@ -20,13 +20,14 @@ import ( "strings" ) + // WidgetAPIService WidgetAPI service type WidgetAPIService service type ApiWidgetsDescribeWidgetRequest struct { - ctx context.Context + ctx context.Context ApiService *WidgetAPIService - name string + name string } func (r ApiWidgetsDescribeWidgetRequest) Execute() (*WidgetsDescribeWidgetResponse, *http.Response, error) { @@ -38,27 +39,26 @@ WidgetsDescribeWidget Describe widget Returns a widget by its name - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param name - @return ApiWidgetsDescribeWidgetRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param name + @return ApiWidgetsDescribeWidgetRequest */ func (a *WidgetAPIService) WidgetsDescribeWidget(ctx context.Context, name string) ApiWidgetsDescribeWidgetRequest { return ApiWidgetsDescribeWidgetRequest{ ApiService: a, - ctx: ctx, - name: name, + ctx: ctx, + name: name, } } // Execute executes the request -// -// @return WidgetsDescribeWidgetResponse +// @return WidgetsDescribeWidgetResponse func (a *WidgetAPIService) WidgetsDescribeWidgetExecute(r ApiWidgetsDescribeWidgetRequest) (*WidgetsDescribeWidgetResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *WidgetsDescribeWidgetResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *WidgetsDescribeWidgetResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WidgetAPIService.WidgetsDescribeWidget") @@ -112,14 +112,14 @@ func (a *WidgetAPIService) WidgetsDescribeWidgetExecute(r ApiWidgetsDescribeWidg body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } @@ -136,7 +136,7 @@ func (a *WidgetAPIService) WidgetsDescribeWidgetExecute(r ApiWidgetsDescribeWidg } type ApiWidgetsListWidgetsRequest struct { - ctx context.Context + ctx context.Context ApiService *WidgetAPIService } @@ -149,25 +149,24 @@ WidgetsListWidgets List widgets Returns a list of all available widgets - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiWidgetsListWidgetsRequest + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiWidgetsListWidgetsRequest */ func (a *WidgetAPIService) WidgetsListWidgets(ctx context.Context) ApiWidgetsListWidgetsRequest { return ApiWidgetsListWidgetsRequest{ ApiService: a, - ctx: ctx, + ctx: ctx, } } // Execute executes the request -// -// @return WidgetsListWidgetsResponse +// @return WidgetsListWidgetsResponse func (a *WidgetAPIService) WidgetsListWidgetsExecute(r ApiWidgetsListWidgetsRequest) (*WidgetsListWidgetsResponse, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *WidgetsListWidgetsResponse + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *WidgetsListWidgetsResponse ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WidgetAPIService.WidgetsListWidgets") @@ -220,14 +219,14 @@ func (a *WidgetAPIService) WidgetsListWidgetsExecute(r ApiWidgetsListWidgetsRequ body: localVarBody, error: localVarHTTPResponse.Status, } - var v GooglerpcStatus - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v + var v GooglerpcStatus + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pkg/openapi_client/client.go b/pkg/openapi_client/client.go index d82aba33e4..51099b9f98 100644 --- a/pkg/openapi_client/client.go +++ b/pkg/openapi_client/client.go @@ -32,13 +32,14 @@ import ( "strings" "time" "unicode/utf8" + ) var ( JsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?json)`) XmlCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?xml)`) queryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`) - queryDescape = strings.NewReplacer("%5B", "[", "%5D", "]") + queryDescape = strings.NewReplacer( "%5B", "[", "%5D", "]" ) ) // APIClient manages communication with the Superplane Organizations API API v1.0 @@ -71,6 +72,8 @@ type APIClient struct { RolesAPI *RolesAPIService + ScriptAPI *ScriptAPIService + SecretAPI *SecretAPIService ServiceAccountsAPI *ServiceAccountsAPIService @@ -109,6 +112,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.MeAPI = (*MeAPIService)(&c.common) c.OrganizationAPI = (*OrganizationAPIService)(&c.common) c.RolesAPI = (*RolesAPIService)(&c.common) + c.ScriptAPI = (*ScriptAPIService)(&c.common) c.SecretAPI = (*SecretAPIService)(&c.common) c.ServiceAccountsAPI = (*ServiceAccountsAPIService)(&c.common) c.TriggerAPI = (*TriggerAPIService)(&c.common) @@ -170,7 +174,7 @@ func typeCheckParameter(obj interface{}, expected string, name string) error { return nil } -func parameterValueToString(obj interface{}, key string) string { +func parameterValueToString( obj interface{}, key string ) string { if reflect.TypeOf(obj).Kind() != reflect.Ptr { if actualObj, ok := obj.(interface{ GetActualInstanceValue() interface{} }); ok { return fmt.Sprintf("%v", actualObj.GetActualInstanceValue()) @@ -178,11 +182,11 @@ func parameterValueToString(obj interface{}, key string) string { return fmt.Sprintf("%v", obj) } - var param, ok = obj.(MappedNullable) + var param,ok = obj.(MappedNullable) if !ok { return "" } - dataMap, err := param.ToMap() + dataMap,err := param.ToMap() if err != nil { return "" } @@ -198,85 +202,85 @@ func parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix stri value = "null" } else { switch v.Kind() { - case reflect.Invalid: - value = "invalid" + case reflect.Invalid: + value = "invalid" - case reflect.Struct: - if t, ok := obj.(MappedNullable); ok { - dataMap, err := t.ToMap() - if err != nil { + case reflect.Struct: + if t,ok := obj.(MappedNullable); ok { + dataMap,err := t.ToMap() + if err != nil { + return + } + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, style, collectionType) return } - parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, style, collectionType) - return - } - if t, ok := obj.(time.Time); ok { - parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339Nano), style, collectionType) - return - } - value = v.Type().String() + " value" - case reflect.Slice: - var indValue = reflect.ValueOf(obj) - if indValue == reflect.ValueOf(nil) { - return - } - var lenIndValue = indValue.Len() - for i := 0; i < lenIndValue; i++ { - var arrayValue = indValue.Index(i) - var keyPrefixForCollectionType = keyPrefix - if style == "deepObject" { - keyPrefixForCollectionType = keyPrefix + "[" + strconv.Itoa(i) + "]" + if t, ok := obj.(time.Time); ok { + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339Nano), style, collectionType) + return } - parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefixForCollectionType, arrayValue.Interface(), style, collectionType) - } - return + value = v.Type().String() + " value" + case reflect.Slice: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + var lenIndValue = indValue.Len() + for i:=0;i 0 { + query[k] = v[0] + } + } + headers := make(map[string]string) + for k, v := range ctx.Request.Header { + if len(v) > 0 { + headers[k] = v[0] + } + } + + raw, err := a.manager.CallPluginRaw("integration/handleRequest", a.pluginName, map[string]any{ + "integration": a.meta.Name, + "context": map[string]any{ + "request": map[string]any{ + "method": ctx.Request.Method, + "path": ctx.Request.URL.Path, + "query": query, + "headers": headers, + "body": string(body), + }, + "organizationId": ctx.OrganizationID, + "baseUrl": ctx.BaseURL, + "webhooksBaseUrl": ctx.WebhooksBaseURL, + }, + }, &CallContext{ + Integration: ctx.Integration, + HTTP: ctx.HTTP, + }) + + if err != nil { + ctx.Logger.Errorf("plugin handleRequest error: %v", err) + http.Error(ctx.Response, "internal server error", http.StatusInternalServerError) + return + } + + if raw == nil { + return + } + + var resp struct { + Action string `json:"action"` + URL string `json:"url"` + Status int `json:"status"` + Message string `json:"message"` + } + if err := json.Unmarshal(raw, &resp); err != nil { + ctx.Logger.Errorf("plugin handleRequest: failed to parse response: %v", err) + return + } + + switch resp.Action { + case "redirect": + http.Redirect(ctx.Response, ctx.Request, resp.URL, http.StatusSeeOther) + case "json": + ctx.Response.WriteHeader(resp.Status) + case "error": + status := resp.Status + if status == 0 { + status = http.StatusInternalServerError + } + http.Error(ctx.Response, resp.Message, status) + } +} + +func (a *PluginIntegrationAdapter) Cleanup(ctx core.IntegrationCleanupContext) error { + _, err := a.manager.CallPluginWithContext("integration/cleanup", a.pluginName, map[string]any{ + "integration": a.meta.Name, + "context": map[string]any{ + "configuration": ctx.Configuration, + "baseUrl": ctx.BaseURL, + "organizationId": ctx.OrganizationID, + }, + }, &CallContext{ + Integration: ctx.Integration, + HTTP: ctx.HTTP, + }) + return err +} + +func (a *PluginIntegrationAdapter) HandleAction(ctx core.IntegrationActionContext) error { + return fmt.Errorf("plugin integration %s does not support actions", a.meta.Name) +} + +func (a *PluginIntegrationAdapter) ListResources(resourceType string, ctx core.ListResourcesContext) ([]core.IntegrationResource, error) { + return nil, nil +} + +// PluginWebhookHandler implements core.WebhookHandler by delegating to the Plugin Host. +type PluginWebhookHandler struct { + integrationName string + pluginName string + manager *Manager +} + +func NewPluginWebhookHandler(integrationName, pluginName string, manager *Manager) *PluginWebhookHandler { + return &PluginWebhookHandler{ + integrationName: integrationName, + pluginName: pluginName, + manager: manager, + } +} + +func (h *PluginWebhookHandler) Setup(ctx core.WebhookHandlerContext) (any, error) { + secret, err := ctx.Webhook.GetSecret() + if err != nil { + return nil, fmt.Errorf("getting webhook secret: %w", err) + } + + result, err := h.manager.CallPluginWithContext("webhookHandler/setup", h.pluginName, map[string]any{ + "integration": h.integrationName, + "context": map[string]any{ + "webhookUrl": ctx.Webhook.GetURL(), + "webhookSecret": string(secret), + "configuration": ctx.Webhook.GetConfiguration(), + }, + }, &CallContext{ + Integration: ctx.Integration, + HTTP: ctx.HTTP, + WebhookCtx: ctx.Webhook, + }) + + if err != nil { + return nil, err + } + + if result != nil && result.Data != nil { + return result.Data, nil + } + + return nil, nil +} + +func (h *PluginWebhookHandler) Cleanup(ctx core.WebhookHandlerContext) error { + _, err := h.manager.CallPluginWithContext("webhookHandler/cleanup", h.pluginName, map[string]any{ + "integration": h.integrationName, + "context": map[string]any{ + "webhookMetadata": ctx.Webhook.GetMetadata(), + "configuration": ctx.Webhook.GetConfiguration(), + }, + }, &CallContext{ + Integration: ctx.Integration, + HTTP: ctx.HTTP, + WebhookCtx: ctx.Webhook, + }) + return err +} + +func (h *PluginWebhookHandler) CompareConfig(a, b any) (bool, error) { + result, err := h.manager.CallPluginWithContext("webhookHandler/compareConfig", h.pluginName, map[string]any{ + "integration": h.integrationName, + "context": map[string]any{ + "a": a, + "b": b, + }, + }, nil) + + if err != nil { + return false, err + } + + if result != nil && result.Data != nil { + if v, ok := result.Data.(bool); ok { + return v, nil + } + } + + return false, nil +} + +func (h *PluginWebhookHandler) Merge(current, requested any) (any, bool, error) { + return current, false, nil +} + +// PluginTriggerAdapter implements core.Trigger using manifest data for metadata +// and JSON-RPC delegation to the Plugin Host for execution methods. +type PluginTriggerAdapter struct { + contribution TriggerContribution + pluginName string + manager *Manager +} + +func NewPluginTriggerAdapter(contribution TriggerContribution, pluginName string, manager *Manager) *PluginTriggerAdapter { + return &PluginTriggerAdapter{ + contribution: contribution, + pluginName: pluginName, + manager: manager, + } +} + +func (a *PluginTriggerAdapter) Name() string { return a.contribution.Name } +func (a *PluginTriggerAdapter) Label() string { return a.contribution.Label } +func (a *PluginTriggerAdapter) Description() string { return a.contribution.Description } +func (a *PluginTriggerAdapter) Icon() string { return a.contribution.Icon } +func (a *PluginTriggerAdapter) Color() string { return a.contribution.Color } + +func (a *PluginTriggerAdapter) Source() string { + if strings.HasPrefix(a.pluginName, "script.") { + return "script" + } + return "plugin" +} + +func (a *PluginTriggerAdapter) Documentation() string { + return a.contribution.Documentation +} + +func (a *PluginTriggerAdapter) ExampleData() map[string]any { + if a.contribution.ExampleData != nil { + return a.contribution.ExampleData + } + return map[string]any{} +} + +func (a *PluginTriggerAdapter) Configuration() []configuration.Field { + if a.contribution.Configuration != nil { + return a.contribution.Configuration + } + return []configuration.Field{} +} + +func (a *PluginTriggerAdapter) Actions() []core.Action { + return []core.Action{} +} + +func (a *PluginTriggerAdapter) Setup(ctx core.TriggerContext) error { + _, err := a.manager.CallPluginWithContext("trigger/setup", a.pluginName, map[string]any{ + "trigger": a.contribution.Name, + "context": map[string]any{ + "configuration": ctx.Configuration, + }, + }, &CallContext{ + Webhook: ctx.Webhook, + HTTP: ctx.HTTP, + Metadata: ctx.Metadata, + Events: ctx.Events, + Secrets: ctx.Secrets, + Integration: ctx.Integration, + }) + return err +} + +func (a *PluginTriggerAdapter) HandleWebhook(ctx core.WebhookRequestContext) (int, error) { + _, err := a.manager.CallPluginWithContext("trigger/handleWebhook", a.pluginName, map[string]any{ + "trigger": a.contribution.Name, + "context": map[string]any{ + "body": string(ctx.Body), + "headers": ctx.Headers, + "workflowId": ctx.WorkflowID, + "nodeId": ctx.NodeID, + "configuration": ctx.Configuration, + }, + }, &CallContext{ + Webhook: ctx.Webhook, + HTTP: ctx.HTTP, + Metadata: ctx.Metadata, + Events: ctx.Events, + }) + + if err != nil { + return http.StatusInternalServerError, err + } + return http.StatusOK, nil +} + +func (a *PluginTriggerAdapter) HandleAction(ctx core.TriggerActionContext) (map[string]any, error) { + return nil, fmt.Errorf("plugin trigger %s does not support actions", a.contribution.Name) +} + +func (a *PluginTriggerAdapter) Cleanup(ctx core.TriggerContext) error { + _, err := a.manager.CallPluginWithContext("trigger/cleanup", a.pluginName, map[string]any{ + "trigger": a.contribution.Name, + "context": map[string]any{ + "configuration": ctx.Configuration, + }, + }, &CallContext{ + Webhook: ctx.Webhook, + HTTP: ctx.HTTP, + Metadata: ctx.Metadata, + Events: ctx.Events, + Secrets: ctx.Secrets, + Integration: ctx.Integration, + }) + return err +} diff --git a/pkg/plugins/http.go b/pkg/plugins/http.go new file mode 100644 index 0000000000..e147cb8fd3 --- /dev/null +++ b/pkg/plugins/http.go @@ -0,0 +1,42 @@ +package plugins + +import ( + "io" + "net/http" + "strings" +) + +func newHTTPRequest(method, url, body string, headers map[string]string) (*http.Request, error) { + var bodyReader io.Reader + if body != "" { + bodyReader = strings.NewReader(body) + } + + req, err := http.NewRequest(method, url, bodyReader) + if err != nil { + return nil, err + } + + for k, v := range headers { + req.Header.Set(k, v) + } + + return req, nil +} + +func readResponseBody(resp *http.Response) (any, error) { + data, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return string(data), nil +} + +func flattenHeaders(h http.Header) map[string]string { + result := make(map[string]string, len(h)) + for k, v := range h { + result[strings.ToLower(k)] = strings.Join(v, ", ") + } + return result +} diff --git a/pkg/plugins/manager.go b/pkg/plugins/manager.go new file mode 100644 index 0000000000..ded8079ec7 --- /dev/null +++ b/pkg/plugins/manager.go @@ -0,0 +1,1069 @@ +package plugins + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sync" + "time" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/superplanehq/superplane/pkg/configuration" + "github.com/superplanehq/superplane/pkg/core" + "github.com/superplanehq/superplane/pkg/models" + "github.com/superplanehq/superplane/pkg/registry" +) + +type LoadedPlugin struct { + Manifest *PluginManifest + Dir string + Activated bool +} + +// CallContext holds the Go-side context objects for an active RPC call. +// The Plugin Host sends callbacks with the callId so we can route +// operations like secrets, webhooks, metadata back to the right context. +type CallContext struct { + Webhook core.NodeWebhookContext + HTTP core.HTTPContext + Metadata core.MetadataContext + Events core.EventContext + Secrets core.SecretsContext + Integration core.IntegrationContext + // WebhookCtx is for the webhook provisioner (WebhookHandler.Setup/Cleanup) + WebhookCtx core.WebhookContext +} + +type Manager struct { + pluginsDir string + registry *registry.Registry + + mu sync.RWMutex + plugins map[string]*LoadedPlugin + host *PluginHostProcess + + activeContexts sync.Map // map[string]*CallContext + + pluginHostPath string + crashCount int + lastCrash time.Time +} + +// RPCResult represents the result returned from a Plugin Host call. +type RPCResult struct { + Action string `json:"action"` + Channel string `json:"channel"` + PayloadType string `json:"payloadType"` + Data any `json:"data"` + Reason string `json:"reason"` + Message string `json:"message"` + Key string `json:"key"` + Value string `json:"value"` +} + +func NewManager(pluginsDir string, reg *registry.Registry) (*Manager, error) { + hostPath := resolvePluginHostPath() + + m := &Manager{ + pluginsDir: pluginsDir, + registry: reg, + plugins: make(map[string]*LoadedPlugin), + pluginHostPath: hostPath, + } + + if _, err := os.Stat(pluginsDir); os.IsNotExist(err) { + log.Infof("Plugin directory %s does not exist, skipping .spx plugin loading", pluginsDir) + } else { + if err := m.loadPlugins(); err != nil { + return nil, fmt.Errorf("loading plugins: %w", err) + } + + if len(m.plugins) > 0 { + if err := m.startHost(); err != nil { + log.WithError(err).Error("Failed to start Plugin Host, plugin execution will be unavailable") + } + } + } + + return m, nil +} + +func resolvePluginHostPath() string { + if p := os.Getenv("SUPERPLANE_PLUGIN_HOST_PATH"); p != "" { + return p + } + + candidates := []string{ + "plugin-host/dist/index.js", + "/app/plugin-host/dist/index.js", + } + + for _, c := range candidates { + if _, err := os.Stat(c); err == nil { + return c + } + } + + return "plugin-host/dist/index.js" +} + +func (m *Manager) loadPlugins() error { + pj, err := ReadPluginsJSON(m.pluginsDir) + if err != nil { + return err + } + + if len(pj.Plugins) == 0 { + log.Info("No plugins installed") + return nil + } + + for _, record := range pj.Plugins { + pluginDir := filepath.Join(m.pluginsDir, record.Name) + manifest, err := ParseManifest(pluginDir) + if err != nil { + log.WithError(err).Errorf("Failed to parse plugin manifest: %s", record.Name) + continue + } + + if err := ValidateManifest(manifest); err != nil { + log.WithError(err).Errorf("Invalid plugin manifest: %s", record.Name) + continue + } + + extensionPath := filepath.Join(pluginDir, "extension.js") + if _, err := os.Stat(extensionPath); os.IsNotExist(err) { + log.Errorf("Plugin %s missing extension.js", record.Name) + continue + } + + m.plugins[record.Name] = &LoadedPlugin{ + Manifest: manifest, + Dir: pluginDir, + } + + m.registerContributions(manifest, record.Name) + log.Infof("Plugin loaded: %s v%s", record.Name, record.Version) + } + + log.Infof("Loaded %d plugins", len(m.plugins)) + return nil +} + +func (m *Manager) registerContributions(manifest *PluginManifest, pluginName string) { + components := make([]core.Component, 0, len(manifest.SuperPlane.Contributes.Components)) + for _, comp := range manifest.SuperPlane.Contributes.Components { + adapter := NewPluginComponentAdapter(comp, pluginName, m) + components = append(components, adapter) + log.Infof(" Registered component: %s", comp.Name) + } + + triggers := make([]core.Trigger, 0, len(manifest.SuperPlane.Contributes.Triggers)) + for _, trig := range manifest.SuperPlane.Contributes.Triggers { + adapter := NewPluginTriggerAdapter(trig, pluginName, m) + triggers = append(triggers, adapter) + log.Infof(" Registered trigger: %s", trig.Name) + } + + integrationMeta := manifest.SuperPlane.Integration + if integrationMeta.Name == "" { + integrationMeta.Name = pluginName + } + if integrationMeta.Label == "" { + integrationMeta.Label = manifest.Name + } + + integration := NewPluginIntegrationAdapter(integrationMeta, pluginName, m, components, triggers) + m.registry.Integrations[integrationMeta.Name] = integration + log.Infof(" Registered integration: %s (%s)", integrationMeta.Name, integrationMeta.Label) + + if integrationMeta.HasWebhookHandler { + webhookHandler := NewPluginWebhookHandler(integrationMeta.Name, pluginName, m) + m.registry.WebhookHandlers[integrationMeta.Name] = webhookHandler + log.Infof(" Registered webhook handler: %s", integrationMeta.Name) + } +} + +func (m *Manager) unregisterContributions(manifest *PluginManifest) { + integrationName := manifest.SuperPlane.Integration.Name + if integrationName == "" { + integrationName = manifest.Name + } + delete(m.registry.Integrations, integrationName) + delete(m.registry.WebhookHandlers, integrationName) +} + +func (m *Manager) startHost() error { + if _, err := os.Stat(m.pluginHostPath); os.IsNotExist(err) { + return fmt.Errorf("plugin host not found at %s", m.pluginHostPath) + } + + host, err := SpawnPluginHost(m.pluginHostPath, m.pluginsDir, m.handleContextCallback) + if err != nil { + return err + } + + m.host = host + + go m.watchHost() + + for name, plugin := range m.plugins { + for _, event := range plugin.Manifest.SuperPlane.ActivationEvents { + if event == "*" { + if err := m.activatePlugin(name); err != nil { + log.WithError(err).Errorf("Failed to activate plugin %s", name) + } + break + } + } + } + + return nil +} + +func (m *Manager) watchHost() { + <-m.host.Done() + + m.mu.Lock() + defer m.mu.Unlock() + + now := time.Now() + if now.Sub(m.lastCrash) < time.Minute { + m.crashCount++ + } else { + m.crashCount = 1 + } + m.lastCrash = now + + if m.crashCount >= 5 { + log.Error("Plugin Host crashed 5 times within 60 seconds, stopping restart attempts") + return + } + + log.Warn("Plugin Host process exited unexpectedly, restarting in 1 second...") + time.Sleep(time.Second) + + for _, plugin := range m.plugins { + plugin.Activated = false + } + + if err := m.startHost(); err != nil { + log.WithError(err).Error("Failed to restart Plugin Host") + } +} + +func (m *Manager) EnsureActivated(pluginName string) error { + m.mu.RLock() + plugin, ok := m.plugins[pluginName] + m.mu.RUnlock() + + if !ok { + return fmt.Errorf("plugin %s not loaded", pluginName) + } + + if plugin.Activated { + return nil + } + + return m.activatePlugin(pluginName) +} + +func (m *Manager) activatePlugin(pluginName string) error { + m.mu.RLock() + plugin, ok := m.plugins[pluginName] + m.mu.RUnlock() + + if !ok { + return fmt.Errorf("plugin %s not loaded", pluginName) + } + + if m.host == nil { + return fmt.Errorf("plugin host not running") + } + + ctx, cancel := context.WithTimeout(context.Background(), DefaultActivationTimeout) + defer cancel() + + _, err := m.host.Call(ctx, "plugin/activate", map[string]any{ + "pluginId": pluginName, + "pluginPath": plugin.Dir, + }) + + if err != nil { + return fmt.Errorf("activating plugin %s: %w", pluginName, err) + } + + m.mu.Lock() + plugin.Activated = true + m.mu.Unlock() + + log.Infof("Plugin activated: %s", pluginName) + return nil +} + +// CallPluginWithContext sends an RPC call to the Plugin Host, registering the +// Go-side context objects so that callbacks (ctx/webhook.setup, ctx/secrets.getKey, etc.) +// can be routed to the correct context. +func (m *Manager) CallPluginRaw(method string, pluginName string, params map[string]any, callCtx *CallContext) (json.RawMessage, error) { + if err := m.EnsureActivated(pluginName); err != nil { + return nil, fmt.Errorf("activating plugin %s: %w", pluginName, err) + } + + params["pluginId"] = pluginName + + if callCtx != nil { + callID := uuid.New().String() + m.activeContexts.Store(callID, callCtx) + defer m.activeContexts.Delete(callID) + + ctxMap, ok := params["context"].(map[string]any) + if !ok { + ctxMap = map[string]any{} + params["context"] = ctxMap + } + ctxMap["callId"] = callID + } + + ctx, cancel := context.WithTimeout(context.Background(), DefaultExecutionTimeout) + defer cancel() + + raw, err := m.host.Call(ctx, method, params) + if err != nil { + return nil, fmt.Errorf("plugin error: %w", err) + } + + return raw, nil +} + +func (m *Manager) CallPluginWithContext(method string, pluginName string, params map[string]any, callCtx *CallContext) (*RPCResult, error) { + if err := m.EnsureActivated(pluginName); err != nil { + return nil, err + } + + callID := uuid.New().String() + + if callCtx != nil { + m.activeContexts.Store(callID, callCtx) + defer m.activeContexts.Delete(callID) + } + + params["pluginId"] = pluginName + + // Inject the callId into the context sub-map so the Plugin Host + // passes it back in all callbacks. + if ctxMap, ok := params["context"].(map[string]any); ok { + ctxMap["callId"] = callID + } + + ctx, cancel := context.WithTimeout(context.Background(), DefaultExecutionTimeout) + defer cancel() + + raw, err := m.host.Call(ctx, method, params) + if err != nil { + return nil, err + } + + if raw == nil || string(raw) == "null" { + return nil, nil + } + + var result RPCResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, nil + } + + return &result, nil +} + +func (m *Manager) getCallContext(params json.RawMessage) (*CallContext, error) { + var p struct { + ContextID string `json:"contextId"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + + v, ok := m.activeContexts.Load(p.ContextID) + if !ok { + return nil, fmt.Errorf("no active context for callId %s", p.ContextID) + } + + return v.(*CallContext), nil +} + +func (m *Manager) handleContextCallback(method string, params json.RawMessage) (any, error) { + log.Debugf("Plugin Host callback: %s", method) + + switch method { + case "ctx/log": + var p struct { + Level string `json:"level"` + Message string `json:"message"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + log.WithField("source", "plugin").Info(p.Message) + return nil, nil + + case "ctx/webhook.setup": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Webhook == nil { + return nil, fmt.Errorf("webhook context not available") + } + url, err := callCtx.Webhook.Setup() + if err != nil { + return nil, err + } + return url, nil + + case "ctx/webhook.getSecret": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Webhook == nil { + return nil, fmt.Errorf("webhook context not available") + } + secret, err := callCtx.Webhook.GetSecret() + if err != nil { + return nil, err + } + return string(secret), nil + + case "ctx/secrets.getKey": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Secrets == nil { + return nil, fmt.Errorf("secrets context not available") + } + var p struct { + SecretName string `json:"secretName"` + KeyName string `json:"keyName"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + val, err := callCtx.Secrets.GetKey(p.SecretName, p.KeyName) + if err != nil { + return nil, err + } + return string(val), nil + + case "ctx/metadata.get": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Metadata == nil { + return nil, nil + } + return callCtx.Metadata.Get(), nil + + case "ctx/metadata.set": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Metadata == nil { + return nil, fmt.Errorf("metadata context not available") + } + var p struct { + Value any `json:"value"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + return nil, callCtx.Metadata.Set(p.Value) + + case "ctx/events.emit": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Events == nil { + return nil, fmt.Errorf("events context not available") + } + var p struct { + PayloadType string `json:"payloadType"` + Payload any `json:"payload"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + return nil, callCtx.Events.Emit(p.PayloadType, p.Payload) + + case "ctx/http.request": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.HTTP == nil { + return nil, fmt.Errorf("http context not available") + } + return m.handleHTTPCallback(callCtx.HTTP, params) + + case "ctx/integration.getMetadata": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + return callCtx.Integration.GetMetadata(), nil + + case "ctx/integration.setMetadata": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + var p struct { + Value any `json:"value"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + callCtx.Integration.SetMetadata(p.Value) + return nil, nil + + case "ctx/integration.getConfig": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + var p struct { + Name string `json:"name"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + val, err := callCtx.Integration.GetConfig(p.Name) + if err != nil { + return nil, err + } + return string(val), nil + + case "ctx/integration.setSecret": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + var p struct { + Name string `json:"name"` + Value string `json:"value"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + return nil, callCtx.Integration.SetSecret(p.Name, []byte(p.Value)) + + case "ctx/integration.getSecrets": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + secrets, err := callCtx.Integration.GetSecrets() + if err != nil { + return nil, err + } + result := make([]map[string]string, len(secrets)) + for i, s := range secrets { + result[i] = map[string]string{"name": s.Name, "value": string(s.Value)} + } + return result, nil + + case "ctx/integration.newBrowserAction": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + var p struct { + Description string `json:"description"` + URL string `json:"url"` + Method string `json:"method"` + FormFields map[string]string `json:"formFields"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + callCtx.Integration.NewBrowserAction(core.BrowserAction{ + Description: p.Description, + URL: p.URL, + Method: p.Method, + FormFields: p.FormFields, + }) + return nil, nil + + case "ctx/integration.removeBrowserAction": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + callCtx.Integration.RemoveBrowserAction() + return nil, nil + + case "ctx/integration.ready": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + callCtx.Integration.Ready() + return nil, nil + + case "ctx/integration.error": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + var p struct { + Message string `json:"message"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + callCtx.Integration.Error(p.Message) + return nil, nil + + case "ctx/integration.requestWebhook": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + var p struct { + Configuration any `json:"configuration"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + return nil, callCtx.Integration.RequestWebhook(p.Configuration) + + case "ctx/integration.id": + callCtx, err := m.getCallContext(params) + if err != nil { + return nil, err + } + if callCtx.Integration == nil { + return nil, fmt.Errorf("integration context not available") + } + return callCtx.Integration.ID().String(), nil + + default: + return nil, fmt.Errorf("unknown callback method: %s", method) + } +} + +func (m *Manager) handleHTTPCallback(httpCtx core.HTTPContext, params json.RawMessage) (any, error) { + var p struct { + Method string `json:"method"` + URL string `json:"url"` + Options struct { + Headers map[string]string `json:"headers"` + Body string `json:"body"` + Timeout int `json:"timeout"` + } `json:"options"` + } + if err := json.Unmarshal(params, &p); err != nil { + return nil, err + } + + req, err := newHTTPRequest(p.Method, p.URL, p.Options.Body, p.Options.Headers) + if err != nil { + return nil, err + } + + resp, err := httpCtx.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, _ := readResponseBody(resp) + + return map[string]any{ + "status": resp.StatusCode, + "headers": flattenHeaders(resp.Header), + "body": body, + }, nil +} + +func (m *Manager) Reload() { + m.mu.Lock() + defer m.mu.Unlock() + + log.Info("Reloading plugins...") + + for _, plugin := range m.plugins { + m.unregisterContributions(plugin.Manifest) + } + + if m.host != nil { + m.host.Kill() + m.host = nil + } + + m.plugins = make(map[string]*LoadedPlugin) + + if err := m.loadPlugins(); err != nil { + log.WithError(err).Error("Failed to reload plugins") + return + } + + if len(m.plugins) > 0 { + if err := m.startHost(); err != nil { + log.WithError(err).Error("Failed to restart Plugin Host after reload") + } + } + + log.Info("Plugin reload complete") +} + +func (m *Manager) Shutdown() { + m.mu.Lock() + defer m.mu.Unlock() + + if m.host != nil { + log.Info("Shutting down Plugin Host") + m.host.Kill() + m.host = nil + } +} + +// LoadScriptsFromDB loads all active scripts from the database and registers +// their contributions. Call this after NewManager during server startup. +func (m *Manager) LoadScriptsFromDB() error { + scripts, err := models.FindActiveScripts() + if err != nil { + return fmt.Errorf("querying active scripts: %w", err) + } + + if len(scripts) == 0 { + return nil + } + + for _, script := range scripts { + scriptID := "script." + script.Name + manifest, err := parseScriptManifest(script.Manifest) + if err != nil { + log.WithError(err).Errorf("Failed to parse manifest for script %s", script.Name) + continue + } + + m.registerScriptContributions(scriptID, manifest) + + m.mu.Lock() + m.plugins[scriptID] = &LoadedPlugin{ + Manifest: manifest, + Dir: "", + Activated: false, + } + m.mu.Unlock() + + log.Infof("Script loaded from DB: %s", scriptID) + } + + if m.host == nil && len(m.plugins) > 0 { + if err := m.startHost(); err != nil { + return fmt.Errorf("starting plugin host for scripts: %w", err) + } + } + + for _, script := range scripts { + scriptID := "script." + script.Name + if err := m.activateScriptInline(scriptID, script.Source); err != nil { + log.WithError(err).Errorf("Failed to activate script %s", scriptID) + } + } + + return nil +} + +// ActivateScript registers and activates an in-app script. +func (m *Manager) ActivateScript(name string, source string, manifestJSON []byte) error { + scriptID := "script." + name + log.Infof("ActivateScript called: scriptID=%s, sourceLen=%d", scriptID, len(source)) + + // Unregister any previous contributions for this script + m.mu.RLock() + existingPlugin, exists := m.plugins[scriptID] + m.mu.RUnlock() + if exists && existingPlugin.Manifest != nil { + m.unregisterScriptContributions(scriptID, existingPlugin.Manifest) + } + + m.mu.Lock() + m.plugins[scriptID] = &LoadedPlugin{ + Manifest: &PluginManifest{}, + Dir: "", + Activated: false, + } + m.mu.Unlock() + + if m.host == nil { + log.Infof("Plugin host not running, starting it now (hostPath=%s)", m.pluginHostPath) + if err := m.startHost(); err != nil { + return fmt.Errorf("starting plugin host: %w", err) + } + log.Info("Plugin host started successfully") + } + + return m.activateScriptInline(scriptID, source) +} + +// DeactivateScript deactivates and unregisters an in-app script. +func (m *Manager) DeactivateScript(name string) error { + scriptID := "script." + name + + m.mu.RLock() + plugin, ok := m.plugins[scriptID] + m.mu.RUnlock() + + if !ok { + return nil + } + + if m.host != nil && plugin.Activated { + ctx, cancel := context.WithTimeout(context.Background(), DefaultActivationTimeout) + defer cancel() + _, _ = m.host.Call(ctx, "plugin/deactivate", map[string]any{ + "pluginId": scriptID, + }) + } + + if plugin.Manifest != nil { + m.unregisterScriptContributions(scriptID, plugin.Manifest) + } + + m.mu.Lock() + delete(m.plugins, scriptID) + m.mu.Unlock() + + return nil +} + +// UpdateScript deactivates the old script and activates the new one. +func (m *Manager) UpdateScript(name string, source string, manifestJSON []byte) error { + if err := m.DeactivateScript(name); err != nil { + return err + } + return m.ActivateScript(name, source, manifestJSON) +} + +func (m *Manager) activateScriptInline(scriptID, source string) error { + log.Infof("activateScriptInline called: scriptID=%s", scriptID) + + if m.host == nil { + if err := m.startHost(); err != nil { + return fmt.Errorf("starting plugin host for script activation: %w", err) + } + } + + ctx, cancel := context.WithTimeout(context.Background(), DefaultActivationTimeout) + defer cancel() + + result, err := m.host.Call(ctx, "plugin/activateInline", map[string]any{ + "pluginId": scriptID, + "source": source, + "manifest": map[string]any{}, + }) + if err != nil { + return fmt.Errorf("activating script %s: %w", scriptID, err) + } + + var parsedResult map[string]any + if err := json.Unmarshal(result, &parsedResult); err != nil { + log.WithError(err).Warnf("Failed to parse activation result for %s", scriptID) + parsedResult = nil + } + log.Infof("Plugin host returned result for %s: %v", scriptID, parsedResult) + + manifest := m.buildManifestFromActivationResult(parsedResult) + log.Infof("Built manifest for %s: components=%d, triggers=%d", + scriptID, + len(manifest.SuperPlane.Contributes.Components), + len(manifest.SuperPlane.Contributes.Triggers)) + + m.registerScriptContributions(scriptID, manifest) + + m.mu.Lock() + if p, ok := m.plugins[scriptID]; ok { + p.Activated = true + p.Manifest = manifest + } + m.mu.Unlock() + + log.Infof("Script activated: %s", scriptID) + return nil +} + +func (m *Manager) buildManifestFromActivationResult(result any) *PluginManifest { + manifest := &PluginManifest{} + + resultMap, ok := result.(map[string]any) + if !ok { + return manifest + } + + if comps, ok := resultMap["components"].([]any); ok { + for _, c := range comps { + comp, ok := c.(map[string]any) + if !ok { + continue + } + + contribution := ComponentContribution{ + Name: stringFromMap(comp, "name"), + Label: stringFromMap(comp, "label"), + Description: stringFromMap(comp, "description"), + Icon: stringFromMap(comp, "icon"), + Color: stringFromMap(comp, "color"), + } + + if channels, ok := comp["outputChannels"].([]any); ok { + for _, ch := range channels { + if chMap, ok := ch.(map[string]any); ok { + contribution.OutputChannels = append(contribution.OutputChannels, OutputChannelManifest{ + Name: stringFromMap(chMap, "name"), + Label: stringFromMap(chMap, "label"), + }) + } + } + } + + if configs, ok := comp["configuration"].([]any); ok { + for _, cfg := range configs { + if cfgMap, ok := cfg.(map[string]any); ok { + field := configuration.Field{ + Name: stringFromMap(cfgMap, "name"), + Label: stringFromMap(cfgMap, "label"), + Type: stringFromMap(cfgMap, "type"), + } + if req, ok := cfgMap["required"].(bool); ok { + field.Required = req + } + contribution.Configuration = append(contribution.Configuration, field) + } + } + } + + manifest.SuperPlane.Contributes.Components = append(manifest.SuperPlane.Contributes.Components, contribution) + } + } + + if trigs, ok := resultMap["triggers"].([]any); ok { + for _, t := range trigs { + trig, ok := t.(map[string]any) + if !ok { + continue + } + + contribution := TriggerContribution{ + Name: stringFromMap(trig, "name"), + Label: stringFromMap(trig, "label"), + Description: stringFromMap(trig, "description"), + Icon: stringFromMap(trig, "icon"), + Color: stringFromMap(trig, "color"), + } + + if configs, ok := trig["configuration"].([]any); ok { + for _, cfg := range configs { + if cfgMap, ok := cfg.(map[string]any); ok { + field := configuration.Field{ + Name: stringFromMap(cfgMap, "name"), + Label: stringFromMap(cfgMap, "label"), + Type: stringFromMap(cfgMap, "type"), + } + if req, ok := cfgMap["required"].(bool); ok { + field.Required = req + } + contribution.Configuration = append(contribution.Configuration, field) + } + } + } + + manifest.SuperPlane.Contributes.Triggers = append(manifest.SuperPlane.Contributes.Triggers, contribution) + } + } + + return manifest +} + +func stringFromMap(m map[string]any, key string) string { + if v, ok := m[key].(string); ok { + return v + } + return "" +} + +func (m *Manager) registerScriptContributions(scriptID string, manifest *PluginManifest) { + for _, comp := range manifest.SuperPlane.Contributes.Components { + adapter := NewPluginComponentAdapter(comp, scriptID, m) + m.registry.Components[comp.Name] = adapter + log.Infof(" Registered script component: %s", comp.Name) + } + + for _, trig := range manifest.SuperPlane.Contributes.Triggers { + adapter := NewPluginTriggerAdapter(trig, scriptID, m) + m.registry.Triggers[trig.Name] = adapter + log.Infof(" Registered script trigger: %s", trig.Name) + } +} + +func (m *Manager) unregisterScriptContributions(scriptID string, manifest *PluginManifest) { + for _, comp := range manifest.SuperPlane.Contributes.Components { + delete(m.registry.Components, comp.Name) + } + for _, trig := range manifest.SuperPlane.Contributes.Triggers { + delete(m.registry.Triggers, trig.Name) + } +} + +func parseScriptManifest(manifestJSON []byte) (*PluginManifest, error) { + if len(manifestJSON) == 0 || string(manifestJSON) == "{}" { + return &PluginManifest{}, nil + } + + var superplaneSection SuperPlaneManifest + if err := json.Unmarshal(manifestJSON, &superplaneSection); err != nil { + return nil, fmt.Errorf("parsing manifest JSON: %w", err) + } + + return &PluginManifest{ + SuperPlane: superplaneSection, + }, nil +} diff --git a/pkg/plugins/manifest.go b/pkg/plugins/manifest.go new file mode 100644 index 0000000000..2395bf4794 --- /dev/null +++ b/pkg/plugins/manifest.go @@ -0,0 +1,177 @@ +package plugins + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "regexp" + "time" + + "github.com/superplanehq/superplane/pkg/configuration" + "github.com/superplanehq/superplane/pkg/core" +) + +var validNameRegexp = regexp.MustCompile(`^[a-z0-9][a-z0-9\-]*(\.[a-z0-9][a-z0-9\-]*)*$`) + +type PluginManifest struct { + Name string `json:"name"` + Version string `json:"version"` + Main string `json:"main"` + Engines struct { + SuperPlane string `json:"superplane"` + } `json:"engines"` + SuperPlane SuperPlaneManifest `json:"superplane"` +} + +type SuperPlaneManifest struct { + ActivationEvents []string `json:"activationEvents"` + Contributes ContributionPoints `json:"contributes"` + Integration IntegrationManifest `json:"integration"` +} + +type IntegrationManifest struct { + Name string `json:"name"` + Label string `json:"label"` + Icon string `json:"icon"` + Description string `json:"description"` + Configuration []configuration.Field `json:"configuration"` + HasWebhookHandler bool `json:"hasWebhookHandler"` +} + +type ContributionPoints struct { + Components []ComponentContribution `json:"components"` + Triggers []TriggerContribution `json:"triggers"` +} + +type ComponentContribution struct { + Name string `json:"name"` + Label string `json:"label"` + Description string `json:"description"` + Documentation string `json:"documentation"` + Icon string `json:"icon"` + Color string `json:"color"` + Configuration []configuration.Field `json:"configuration"` + OutputChannels []OutputChannelManifest `json:"outputChannels"` + ExampleOutput map[string]any `json:"exampleOutput"` +} + +type TriggerContribution struct { + Name string `json:"name"` + Label string `json:"label"` + Description string `json:"description"` + Documentation string `json:"documentation"` + Icon string `json:"icon"` + Color string `json:"color"` + Configuration []configuration.Field `json:"configuration"` + ExampleData map[string]any `json:"exampleData"` +} + +type OutputChannelManifest struct { + Name string `json:"name"` + Label string `json:"label"` + Description string `json:"description"` +} + +func (o OutputChannelManifest) ToCoreOutputChannel() core.OutputChannel { + return core.OutputChannel{ + Name: o.Name, + Label: o.Label, + Description: o.Description, + } +} + +type PluginsJSON struct { + Plugins []PluginRecord `json:"plugins"` +} + +type PluginRecord struct { + Name string `json:"name"` + Version string `json:"version"` + InstalledAt time.Time `json:"installedAt"` +} + +func ParseManifest(pluginDir string) (*PluginManifest, error) { + data, err := os.ReadFile(filepath.Join(pluginDir, "package.json")) + if err != nil { + return nil, fmt.Errorf("reading package.json: %w", err) + } + + var manifest PluginManifest + if err := json.Unmarshal(data, &manifest); err != nil { + return nil, fmt.Errorf("parsing package.json: %w", err) + } + + return &manifest, nil +} + +func ValidateManifest(m *PluginManifest) error { + if m.Name == "" { + return fmt.Errorf("manifest missing required field: name") + } + if m.Version == "" { + return fmt.Errorf("manifest missing required field: version") + } + if m.Engines.SuperPlane == "" { + return fmt.Errorf("manifest missing required field: engines.superplane") + } + if len(m.SuperPlane.ActivationEvents) == 0 { + return fmt.Errorf("manifest missing required field: superplane.activationEvents") + } + + for _, c := range m.SuperPlane.Contributes.Components { + if err := validateContributedName(c.Name); err != nil { + return fmt.Errorf("component %q: %w", c.Name, err) + } + if c.Label == "" { + return fmt.Errorf("component %q missing required field: label", c.Name) + } + } + + for _, t := range m.SuperPlane.Contributes.Triggers { + if err := validateContributedName(t.Name); err != nil { + return fmt.Errorf("trigger %q: %w", t.Name, err) + } + if t.Label == "" { + return fmt.Errorf("trigger %q missing required field: label", t.Name) + } + } + + return nil +} + +func validateContributedName(name string) error { + if name == "" { + return fmt.Errorf("name is required") + } + if !validNameRegexp.MatchString(name) { + return fmt.Errorf("name %q must be lowercase alphanumeric with hyphens and dots", name) + } + return nil +} + +func ReadPluginsJSON(pluginsDir string) (*PluginsJSON, error) { + data, err := os.ReadFile(filepath.Join(pluginsDir, "plugins.json")) + if err != nil { + if os.IsNotExist(err) { + return &PluginsJSON{}, nil + } + return nil, fmt.Errorf("reading plugins.json: %w", err) + } + + var pj PluginsJSON + if err := json.Unmarshal(data, &pj); err != nil { + return nil, fmt.Errorf("parsing plugins.json: %w", err) + } + + return &pj, nil +} + +func WritePluginsJSON(pluginsDir string, pj *PluginsJSON) error { + data, err := json.MarshalIndent(pj, "", " ") + if err != nil { + return fmt.Errorf("marshaling plugins.json: %w", err) + } + + return os.WriteFile(filepath.Join(pluginsDir, "plugins.json"), data, 0644) +} diff --git a/pkg/plugins/rpc.go b/pkg/plugins/rpc.go new file mode 100644 index 0000000000..ed795efc99 --- /dev/null +++ b/pkg/plugins/rpc.go @@ -0,0 +1,237 @@ +package plugins + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "os/exec" + "sync" + "sync/atomic" + "time" + + log "github.com/sirupsen/logrus" +) + +const DefaultExecutionTimeout = 30 * time.Second +const DefaultActivationTimeout = 10 * time.Second + +type jsonRPCRequest struct { + JSONRPC string `json:"jsonrpc"` + ID int64 `json:"id,omitempty"` + Method string `json:"method"` + Params any `json:"params,omitempty"` +} + +type jsonRPCResponse struct { + JSONRPC string `json:"jsonrpc"` + ID int64 `json:"id,omitempty"` + Result json.RawMessage `json:"result,omitempty"` + Error *jsonRPCError `json:"error,omitempty"` +} + +type jsonRPCError struct { + Code int `json:"code"` + Message string `json:"message"` + Data any `json:"data,omitempty"` +} + +// ContextCallbackHandler is called when the Plugin Host sends a request +// back to Go for context operations (secrets, http, metadata, etc.). +type ContextCallbackHandler func(method string, params json.RawMessage) (any, error) + +type PluginHostProcess struct { + cmd *exec.Cmd + stdin io.WriteCloser + stdout io.ReadCloser + stderr io.ReadCloser + + nextID atomic.Int64 + pending sync.Map // map[int64]chan *jsonRPCResponse + writeMu sync.Mutex + + callbackHandler ContextCallbackHandler + + done chan struct{} +} + +func SpawnPluginHost(pluginHostPath string, pluginsDir string, callbackHandler ContextCallbackHandler) (*PluginHostProcess, error) { + cmd := exec.Command("node", pluginHostPath) + cmd.Env = append(cmd.Environ(), fmt.Sprintf("SUPERPLANE_PLUGINS_DIR=%s", pluginsDir)) + + stdin, err := cmd.StdinPipe() + if err != nil { + return nil, fmt.Errorf("creating stdin pipe: %w", err) + } + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("creating stdout pipe: %w", err) + } + + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, fmt.Errorf("creating stderr pipe: %w", err) + } + + if err := cmd.Start(); err != nil { + return nil, fmt.Errorf("starting plugin host: %w", err) + } + + p := &PluginHostProcess{ + cmd: cmd, + stdin: stdin, + stdout: stdout, + stderr: stderr, + callbackHandler: callbackHandler, + done: make(chan struct{}), + } + + go p.readLoop() + go p.readStderr() + + return p, nil +} + +func (p *PluginHostProcess) readLoop() { + defer close(p.done) + scanner := bufio.NewScanner(p.stdout) + scanner.Buffer(make([]byte, 0, 1024*1024), 1024*1024) + + for scanner.Scan() { + line := scanner.Bytes() + + var msg json.RawMessage + if err := json.Unmarshal(line, &msg); err != nil { + log.WithError(err).Warn("Plugin Host: invalid JSON from stdout") + continue + } + + // Determine if this is a response (has "id" + ("result" or "error")) + // or a request from the Plugin Host (has "method"). + var peek struct { + ID *int64 `json:"id"` + Method string `json:"method"` + Result json.RawMessage `json:"result"` + Error *jsonRPCError `json:"error"` + } + if err := json.Unmarshal(line, &peek); err != nil { + continue + } + + if peek.Method != "" && peek.ID != nil { + // This is a request FROM the Plugin Host (e.g., ctx/secrets.getKey) + go p.handleCallback(*peek.ID, peek.Method, line) + continue + } + + if peek.ID != nil { + // This is a response to one of our requests + var resp jsonRPCResponse + if err := json.Unmarshal(line, &resp); err != nil { + log.WithError(err).Warn("Plugin Host: failed to parse response") + continue + } + + if ch, ok := p.pending.LoadAndDelete(resp.ID); ok { + ch.(chan *jsonRPCResponse) <- &resp + } + } + } + + if err := scanner.Err(); err != nil { + log.WithError(err).Error("Plugin Host stdout reader error") + } +} + +func (p *PluginHostProcess) readStderr() { + scanner := bufio.NewScanner(p.stderr) + for scanner.Scan() { + log.WithField("source", "plugin-host").Warn(scanner.Text()) + } +} + +func (p *PluginHostProcess) handleCallback(id int64, method string, raw []byte) { + var req struct { + Params json.RawMessage `json:"params"` + } + _ = json.Unmarshal(raw, &req) + + result, err := p.callbackHandler(method, req.Params) + + var resp jsonRPCResponse + resp.JSONRPC = "2.0" + resp.ID = id + + if err != nil { + resp.Error = &jsonRPCError{ + Code: -32000, + Message: err.Error(), + } + } else { + resultBytes, _ := json.Marshal(result) + resp.Result = resultBytes + } + + p.writeMessage(resp) +} + +func (p *PluginHostProcess) Call(ctx context.Context, method string, params any) (json.RawMessage, error) { + id := p.nextID.Add(1) + + req := jsonRPCRequest{ + JSONRPC: "2.0", + ID: id, + Method: method, + Params: params, + } + + respCh := make(chan *jsonRPCResponse, 1) + p.pending.Store(id, respCh) + defer p.pending.Delete(id) + + if err := p.writeMessage(req); err != nil { + return nil, fmt.Errorf("writing to plugin host: %w", err) + } + + select { + case resp := <-respCh: + if resp.Error != nil { + return nil, fmt.Errorf("plugin error: %s", resp.Error.Message) + } + return resp.Result, nil + case <-ctx.Done(): + return nil, ctx.Err() + case <-p.done: + return nil, fmt.Errorf("plugin host process exited") + } +} + +func (p *PluginHostProcess) writeMessage(msg any) error { + data, err := json.Marshal(msg) + if err != nil { + return err + } + + p.writeMu.Lock() + defer p.writeMu.Unlock() + + data = append(data, '\n') + _, err = p.stdin.Write(data) + return err +} + +func (p *PluginHostProcess) Kill() { + _ = p.stdin.Close() + _ = p.cmd.Process.Kill() + _ = p.cmd.Wait() +} + +func (p *PluginHostProcess) Wait() error { + return p.cmd.Wait() +} + +func (p *PluginHostProcess) Done() <-chan struct{} { + return p.done +} diff --git a/pkg/protos/components/components.pb.go b/pkg/protos/components/components.pb.go index 9fb94ceff5..9268033a96 100644 --- a/pkg/protos/components/components.pb.go +++ b/pkg/protos/components/components.pb.go @@ -256,6 +256,7 @@ type Component struct { Icon string `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` Color string `protobuf:"bytes,7,opt,name=color,proto3" json:"color,omitempty"` ExampleOutput *_struct.Struct `protobuf:"bytes,8,opt,name=example_output,json=exampleOutput,proto3" json:"example_output,omitempty"` + Source string `protobuf:"bytes,9,opt,name=source,proto3" json:"source,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -346,6 +347,13 @@ func (x *Component) GetExampleOutput() *_struct.Struct { return nil } +func (x *Component) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + type OutputChannel struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1172,7 +1180,7 @@ const file_components_proto_rawDesc = "" + "\x18DescribeComponentRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\"[\n" + "\x19DescribeComponentResponse\x12>\n" + - "\tcomponent\x18\x01 \x01(\v2 .Superplane.Components.ComponentR\tcomponent\"\xd7\x02\n" + + "\tcomponent\x18\x01 \x01(\v2 .Superplane.Components.ComponentR\tcomponent\"\xef\x02\n" + "\tComponent\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + "\x05label\x18\x02 \x01(\tR\x05label\x12 \n" + @@ -1181,7 +1189,8 @@ const file_components_proto_rawDesc = "" + "\x0foutput_channels\x18\x05 \x03(\v2$.Superplane.Components.OutputChannelR\x0eoutputChannels\x12\x12\n" + "\x04icon\x18\x06 \x01(\tR\x04icon\x12\x14\n" + "\x05color\x18\a \x01(\tR\x05color\x12>\n" + - "\x0eexample_output\x18\b \x01(\v2\x17.google.protobuf.StructR\rexampleOutput\"[\n" + + "\x0eexample_output\x18\b \x01(\v2\x17.google.protobuf.StructR\rexampleOutput\x12\x16\n" + + "\x06source\x18\t \x01(\tR\x06source\"[\n" + "\rOutputChannel\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + "\x05label\x18\x02 \x01(\tR\x05label\x12 \n" + diff --git a/pkg/protos/scripts/scripts.pb.go b/pkg/protos/scripts/scripts.pb.go new file mode 100644 index 0000000000..304559dd25 --- /dev/null +++ b/pkg/protos/scripts/scripts.pb.go @@ -0,0 +1,828 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v3.15.8 +// source: scripts.proto + +package scripts + +import ( + timestamp "github.com/golang/protobuf/ptypes/timestamp" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ListScriptsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListScriptsRequest) Reset() { + *x = ListScriptsRequest{} + mi := &file_scripts_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListScriptsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListScriptsRequest) ProtoMessage() {} + +func (x *ListScriptsRequest) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListScriptsRequest.ProtoReflect.Descriptor instead. +func (*ListScriptsRequest) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{0} +} + +type ListScriptsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Scripts []*Script `protobuf:"bytes,1,rep,name=scripts,proto3" json:"scripts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListScriptsResponse) Reset() { + *x = ListScriptsResponse{} + mi := &file_scripts_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListScriptsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListScriptsResponse) ProtoMessage() {} + +func (x *ListScriptsResponse) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListScriptsResponse.ProtoReflect.Descriptor instead. +func (*ListScriptsResponse) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{1} +} + +func (x *ListScriptsResponse) GetScripts() []*Script { + if x != nil { + return x.Scripts + } + return nil +} + +type DescribeScriptRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DescribeScriptRequest) Reset() { + *x = DescribeScriptRequest{} + mi := &file_scripts_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DescribeScriptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DescribeScriptRequest) ProtoMessage() {} + +func (x *DescribeScriptRequest) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DescribeScriptRequest.ProtoReflect.Descriptor instead. +func (*DescribeScriptRequest) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{2} +} + +func (x *DescribeScriptRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DescribeScriptResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Script *Script `protobuf:"bytes,1,opt,name=script,proto3" json:"script,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DescribeScriptResponse) Reset() { + *x = DescribeScriptResponse{} + mi := &file_scripts_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DescribeScriptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DescribeScriptResponse) ProtoMessage() {} + +func (x *DescribeScriptResponse) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DescribeScriptResponse.ProtoReflect.Descriptor instead. +func (*DescribeScriptResponse) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{3} +} + +func (x *DescribeScriptResponse) GetScript() *Script { + if x != nil { + return x.Script + } + return nil +} + +type CreateScriptRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Script *Script `protobuf:"bytes,1,opt,name=script,proto3" json:"script,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateScriptRequest) Reset() { + *x = CreateScriptRequest{} + mi := &file_scripts_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateScriptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateScriptRequest) ProtoMessage() {} + +func (x *CreateScriptRequest) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateScriptRequest.ProtoReflect.Descriptor instead. +func (*CreateScriptRequest) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateScriptRequest) GetScript() *Script { + if x != nil { + return x.Script + } + return nil +} + +type CreateScriptResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Script *Script `protobuf:"bytes,1,opt,name=script,proto3" json:"script,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateScriptResponse) Reset() { + *x = CreateScriptResponse{} + mi := &file_scripts_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateScriptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateScriptResponse) ProtoMessage() {} + +func (x *CreateScriptResponse) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateScriptResponse.ProtoReflect.Descriptor instead. +func (*CreateScriptResponse) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateScriptResponse) GetScript() *Script { + if x != nil { + return x.Script + } + return nil +} + +type UpdateScriptRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Script *Script `protobuf:"bytes,2,opt,name=script,proto3" json:"script,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateScriptRequest) Reset() { + *x = UpdateScriptRequest{} + mi := &file_scripts_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateScriptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateScriptRequest) ProtoMessage() {} + +func (x *UpdateScriptRequest) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateScriptRequest.ProtoReflect.Descriptor instead. +func (*UpdateScriptRequest) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{6} +} + +func (x *UpdateScriptRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateScriptRequest) GetScript() *Script { + if x != nil { + return x.Script + } + return nil +} + +type UpdateScriptResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Script *Script `protobuf:"bytes,1,opt,name=script,proto3" json:"script,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateScriptResponse) Reset() { + *x = UpdateScriptResponse{} + mi := &file_scripts_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateScriptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateScriptResponse) ProtoMessage() {} + +func (x *UpdateScriptResponse) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateScriptResponse.ProtoReflect.Descriptor instead. +func (*UpdateScriptResponse) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateScriptResponse) GetScript() *Script { + if x != nil { + return x.Script + } + return nil +} + +type DeleteScriptRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteScriptRequest) Reset() { + *x = DeleteScriptRequest{} + mi := &file_scripts_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteScriptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteScriptRequest) ProtoMessage() {} + +func (x *DeleteScriptRequest) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteScriptRequest.ProtoReflect.Descriptor instead. +func (*DeleteScriptRequest) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{8} +} + +func (x *DeleteScriptRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteScriptResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteScriptResponse) Reset() { + *x = DeleteScriptResponse{} + mi := &file_scripts_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteScriptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteScriptResponse) ProtoMessage() {} + +func (x *DeleteScriptResponse) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteScriptResponse.ProtoReflect.Descriptor instead. +func (*DeleteScriptResponse) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{9} +} + +type GenerateScriptRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ScriptId string `protobuf:"bytes,1,opt,name=script_id,json=scriptId,proto3" json:"script_id,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GenerateScriptRequest) Reset() { + *x = GenerateScriptRequest{} + mi := &file_scripts_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateScriptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateScriptRequest) ProtoMessage() {} + +func (x *GenerateScriptRequest) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenerateScriptRequest.ProtoReflect.Descriptor instead. +func (*GenerateScriptRequest) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{10} +} + +func (x *GenerateScriptRequest) GetScriptId() string { + if x != nil { + return x.ScriptId + } + return "" +} + +func (x *GenerateScriptRequest) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type GenerateScriptResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"` + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GenerateScriptResponse) Reset() { + *x = GenerateScriptResponse{} + mi := &file_scripts_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateScriptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateScriptResponse) ProtoMessage() {} + +func (x *GenerateScriptResponse) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenerateScriptResponse.ProtoReflect.Descriptor instead. +func (*GenerateScriptResponse) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{11} +} + +func (x *GenerateScriptResponse) GetResponse() string { + if x != nil { + return x.Response + } + return "" +} + +func (x *GenerateScriptResponse) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +type Script struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + OrganizationId string `protobuf:"bytes,2,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + Source string `protobuf:"bytes,6,opt,name=source,proto3" json:"source,omitempty"` + ManifestJson string `protobuf:"bytes,7,opt,name=manifest_json,json=manifestJson,proto3" json:"manifest_json,omitempty"` + Status string `protobuf:"bytes,8,opt,name=status,proto3" json:"status,omitempty"` + CreatedBy string `protobuf:"bytes,9,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + CreatedAt *timestamp.Timestamp `protobuf:"bytes,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamp.Timestamp `protobuf:"bytes,11,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Script) Reset() { + *x = Script{} + mi := &file_scripts_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Script) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Script) ProtoMessage() {} + +func (x *Script) ProtoReflect() protoreflect.Message { + mi := &file_scripts_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Script.ProtoReflect.Descriptor instead. +func (*Script) Descriptor() ([]byte, []int) { + return file_scripts_proto_rawDescGZIP(), []int{12} +} + +func (x *Script) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Script) GetOrganizationId() string { + if x != nil { + return x.OrganizationId + } + return "" +} + +func (x *Script) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Script) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *Script) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Script) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Script) GetManifestJson() string { + if x != nil { + return x.ManifestJson + } + return "" +} + +func (x *Script) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *Script) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *Script) GetCreatedAt() *timestamp.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Script) GetUpdatedAt() *timestamp.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +var File_scripts_proto protoreflect.FileDescriptor + +const file_scripts_proto_rawDesc = "" + + "\n" + + "\rscripts.proto\x12\x12Superplane.Scripts\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/api/annotations.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\x14\n" + + "\x12ListScriptsRequest\"K\n" + + "\x13ListScriptsResponse\x124\n" + + "\ascripts\x18\x01 \x03(\v2\x1a.Superplane.Scripts.ScriptR\ascripts\"'\n" + + "\x15DescribeScriptRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"L\n" + + "\x16DescribeScriptResponse\x122\n" + + "\x06script\x18\x01 \x01(\v2\x1a.Superplane.Scripts.ScriptR\x06script\"I\n" + + "\x13CreateScriptRequest\x122\n" + + "\x06script\x18\x01 \x01(\v2\x1a.Superplane.Scripts.ScriptR\x06script\"J\n" + + "\x14CreateScriptResponse\x122\n" + + "\x06script\x18\x01 \x01(\v2\x1a.Superplane.Scripts.ScriptR\x06script\"Y\n" + + "\x13UpdateScriptRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x122\n" + + "\x06script\x18\x02 \x01(\v2\x1a.Superplane.Scripts.ScriptR\x06script\"J\n" + + "\x14UpdateScriptResponse\x122\n" + + "\x06script\x18\x01 \x01(\v2\x1a.Superplane.Scripts.ScriptR\x06script\"%\n" + + "\x13DeleteScriptRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x16\n" + + "\x14DeleteScriptResponse\"N\n" + + "\x15GenerateScriptRequest\x12\x1b\n" + + "\tscript_id\x18\x01 \x01(\tR\bscriptId\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\"L\n" + + "\x16GenerateScriptResponse\x12\x1a\n" + + "\bresponse\x18\x01 \x01(\tR\bresponse\x12\x16\n" + + "\x06source\x18\x02 \x01(\tR\x06source\"\xf7\x02\n" + + "\x06Script\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12'\n" + + "\x0forganization_id\x18\x02 \x01(\tR\x0eorganizationId\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12\x14\n" + + "\x05label\x18\x04 \x01(\tR\x05label\x12 \n" + + "\vdescription\x18\x05 \x01(\tR\vdescription\x12\x16\n" + + "\x06source\x18\x06 \x01(\tR\x06source\x12#\n" + + "\rmanifest_json\x18\a \x01(\tR\fmanifestJson\x12\x16\n" + + "\x06status\x18\b \x01(\tR\x06status\x12\x1d\n" + + "\n" + + "created_by\x18\t \x01(\tR\tcreatedBy\x129\n" + + "\n" + + "created_at\x18\n" + + " \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt2\xa9\t\n" + + "\aScripts\x12\xc3\x01\n" + + "\vListScripts\x12&.Superplane.Scripts.ListScriptsRequest\x1a'.Superplane.Scripts.ListScriptsResponse\"c\x92AI\n" + + "\x06Script\x12\fList scripts\x1a1Returns a list of all scripts in the organization\x82\xd3\xe4\x93\x02\x11\x12\x0f/api/v1/scripts\x12\xb3\x01\n" + + "\x0eDescribeScript\x12).Superplane.Scripts.DescribeScriptRequest\x1a*.Superplane.Scripts.DescribeScriptResponse\"J\x92A+\n" + + "\x06Script\x12\x0fDescribe script\x1a\x10Returns a script\x82\xd3\xe4\x93\x02\x16\x12\x14/api/v1/scripts/{id}\x12\xb4\x01\n" + + "\fCreateScript\x12'.Superplane.Scripts.CreateScriptRequest\x1a(.Superplane.Scripts.CreateScriptResponse\"Q\x92A4\n" + + "\x06Script\x12\rCreate script\x1a\x1bCreates a new in-app script\x82\xd3\xe4\x93\x02\x14:\x01*\"\x0f/api/v1/scripts\x12\xb8\x01\n" + + "\fUpdateScript\x12'.Superplane.Scripts.UpdateScriptRequest\x1a(.Superplane.Scripts.UpdateScriptResponse\"U\x92A3\n" + + "\x06Script\x12\rUpdate script\x1a\x1aUpdates an existing script\x82\xd3\xe4\x93\x02\x19:\x01*2\x14/api/v1/scripts/{id}\x12\xb5\x01\n" + + "\fDeleteScript\x12'.Superplane.Scripts.DeleteScriptRequest\x1a(.Superplane.Scripts.DeleteScriptResponse\"R\x92A3\n" + + "\x06Script\x12\rDelete script\x1a\x1aDeletes an existing script\x82\xd3\xe4\x93\x02\x16*\x14/api/v1/scripts/{id}\x12\xf7\x01\n" + + "\x0eGenerateScript\x12).Superplane.Scripts.GenerateScriptRequest\x1a*.Superplane.Scripts.GenerateScriptResponse\"\x8d\x01\x92A[\n" + + "\x06Script\x12\x0fGenerate script\x1a@Uses AI to generate or update script code based on a user prompt\x82\xd3\xe4\x93\x02):\x01*\"$/api/v1/scripts/{script_id}/generateB\xcc\x01\x92A\x91\x01\x12g\n" + + "\x16Superplane Scripts API\x12!API for Superplane in-app scripts\"%\n" + + "\vAPI Support\x1a\x16support@superplane.com2\x031.0*\x02\x01\x022\x10application/json:\x10application/jsonZ5github.com/superplanehq/superplane/pkg/protos/scriptsb\x06proto3" + +var ( + file_scripts_proto_rawDescOnce sync.Once + file_scripts_proto_rawDescData []byte +) + +func file_scripts_proto_rawDescGZIP() []byte { + file_scripts_proto_rawDescOnce.Do(func() { + file_scripts_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_scripts_proto_rawDesc), len(file_scripts_proto_rawDesc))) + }) + return file_scripts_proto_rawDescData +} + +var file_scripts_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_scripts_proto_goTypes = []any{ + (*ListScriptsRequest)(nil), // 0: Superplane.Scripts.ListScriptsRequest + (*ListScriptsResponse)(nil), // 1: Superplane.Scripts.ListScriptsResponse + (*DescribeScriptRequest)(nil), // 2: Superplane.Scripts.DescribeScriptRequest + (*DescribeScriptResponse)(nil), // 3: Superplane.Scripts.DescribeScriptResponse + (*CreateScriptRequest)(nil), // 4: Superplane.Scripts.CreateScriptRequest + (*CreateScriptResponse)(nil), // 5: Superplane.Scripts.CreateScriptResponse + (*UpdateScriptRequest)(nil), // 6: Superplane.Scripts.UpdateScriptRequest + (*UpdateScriptResponse)(nil), // 7: Superplane.Scripts.UpdateScriptResponse + (*DeleteScriptRequest)(nil), // 8: Superplane.Scripts.DeleteScriptRequest + (*DeleteScriptResponse)(nil), // 9: Superplane.Scripts.DeleteScriptResponse + (*GenerateScriptRequest)(nil), // 10: Superplane.Scripts.GenerateScriptRequest + (*GenerateScriptResponse)(nil), // 11: Superplane.Scripts.GenerateScriptResponse + (*Script)(nil), // 12: Superplane.Scripts.Script + (*timestamp.Timestamp)(nil), // 13: google.protobuf.Timestamp +} +var file_scripts_proto_depIdxs = []int32{ + 12, // 0: Superplane.Scripts.ListScriptsResponse.scripts:type_name -> Superplane.Scripts.Script + 12, // 1: Superplane.Scripts.DescribeScriptResponse.script:type_name -> Superplane.Scripts.Script + 12, // 2: Superplane.Scripts.CreateScriptRequest.script:type_name -> Superplane.Scripts.Script + 12, // 3: Superplane.Scripts.CreateScriptResponse.script:type_name -> Superplane.Scripts.Script + 12, // 4: Superplane.Scripts.UpdateScriptRequest.script:type_name -> Superplane.Scripts.Script + 12, // 5: Superplane.Scripts.UpdateScriptResponse.script:type_name -> Superplane.Scripts.Script + 13, // 6: Superplane.Scripts.Script.created_at:type_name -> google.protobuf.Timestamp + 13, // 7: Superplane.Scripts.Script.updated_at:type_name -> google.protobuf.Timestamp + 0, // 8: Superplane.Scripts.Scripts.ListScripts:input_type -> Superplane.Scripts.ListScriptsRequest + 2, // 9: Superplane.Scripts.Scripts.DescribeScript:input_type -> Superplane.Scripts.DescribeScriptRequest + 4, // 10: Superplane.Scripts.Scripts.CreateScript:input_type -> Superplane.Scripts.CreateScriptRequest + 6, // 11: Superplane.Scripts.Scripts.UpdateScript:input_type -> Superplane.Scripts.UpdateScriptRequest + 8, // 12: Superplane.Scripts.Scripts.DeleteScript:input_type -> Superplane.Scripts.DeleteScriptRequest + 10, // 13: Superplane.Scripts.Scripts.GenerateScript:input_type -> Superplane.Scripts.GenerateScriptRequest + 1, // 14: Superplane.Scripts.Scripts.ListScripts:output_type -> Superplane.Scripts.ListScriptsResponse + 3, // 15: Superplane.Scripts.Scripts.DescribeScript:output_type -> Superplane.Scripts.DescribeScriptResponse + 5, // 16: Superplane.Scripts.Scripts.CreateScript:output_type -> Superplane.Scripts.CreateScriptResponse + 7, // 17: Superplane.Scripts.Scripts.UpdateScript:output_type -> Superplane.Scripts.UpdateScriptResponse + 9, // 18: Superplane.Scripts.Scripts.DeleteScript:output_type -> Superplane.Scripts.DeleteScriptResponse + 11, // 19: Superplane.Scripts.Scripts.GenerateScript:output_type -> Superplane.Scripts.GenerateScriptResponse + 14, // [14:20] is the sub-list for method output_type + 8, // [8:14] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_scripts_proto_init() } +func file_scripts_proto_init() { + if File_scripts_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_scripts_proto_rawDesc), len(file_scripts_proto_rawDesc)), + NumEnums: 0, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_scripts_proto_goTypes, + DependencyIndexes: file_scripts_proto_depIdxs, + MessageInfos: file_scripts_proto_msgTypes, + }.Build() + File_scripts_proto = out.File + file_scripts_proto_goTypes = nil + file_scripts_proto_depIdxs = nil +} diff --git a/pkg/protos/scripts/scripts.pb.gw.go b/pkg/protos/scripts/scripts.pb.gw.go new file mode 100644 index 0000000000..51a995ed3e --- /dev/null +++ b/pkg/protos/scripts/scripts.pb.gw.go @@ -0,0 +1,526 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: scripts.proto + +/* +Package scripts is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package scripts + +import ( + "context" + "errors" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var ( + _ codes.Code + _ io.Reader + _ status.Status + _ = errors.New + _ = runtime.String + _ = utilities.NewDoubleArray + _ = metadata.Join +) + +func request_Scripts_ListScripts_0(ctx context.Context, marshaler runtime.Marshaler, client ScriptsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq ListScriptsRequest + metadata runtime.ServerMetadata + ) + io.Copy(io.Discard, req.Body) + msg, err := client.ListScripts(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Scripts_ListScripts_0(ctx context.Context, marshaler runtime.Marshaler, server ScriptsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq ListScriptsRequest + metadata runtime.ServerMetadata + ) + msg, err := server.ListScripts(ctx, &protoReq) + return msg, metadata, err +} + +func request_Scripts_DescribeScript_0(ctx context.Context, marshaler runtime.Marshaler, client ScriptsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq DescribeScriptRequest + metadata runtime.ServerMetadata + err error + ) + io.Copy(io.Discard, req.Body) + val, ok := pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + msg, err := client.DescribeScript(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Scripts_DescribeScript_0(ctx context.Context, marshaler runtime.Marshaler, server ScriptsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq DescribeScriptRequest + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + msg, err := server.DescribeScript(ctx, &protoReq) + return msg, metadata, err +} + +func request_Scripts_CreateScript_0(ctx context.Context, marshaler runtime.Marshaler, client ScriptsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq CreateScriptRequest + metadata runtime.ServerMetadata + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.CreateScript(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Scripts_CreateScript_0(ctx context.Context, marshaler runtime.Marshaler, server ScriptsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq CreateScriptRequest + metadata runtime.ServerMetadata + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.CreateScript(ctx, &protoReq) + return msg, metadata, err +} + +func request_Scripts_UpdateScript_0(ctx context.Context, marshaler runtime.Marshaler, client ScriptsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq UpdateScriptRequest + metadata runtime.ServerMetadata + err error + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + val, ok := pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + msg, err := client.UpdateScript(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Scripts_UpdateScript_0(ctx context.Context, marshaler runtime.Marshaler, server ScriptsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq UpdateScriptRequest + metadata runtime.ServerMetadata + err error + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + val, ok := pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + msg, err := server.UpdateScript(ctx, &protoReq) + return msg, metadata, err +} + +func request_Scripts_DeleteScript_0(ctx context.Context, marshaler runtime.Marshaler, client ScriptsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq DeleteScriptRequest + metadata runtime.ServerMetadata + err error + ) + io.Copy(io.Discard, req.Body) + val, ok := pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + msg, err := client.DeleteScript(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Scripts_DeleteScript_0(ctx context.Context, marshaler runtime.Marshaler, server ScriptsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq DeleteScriptRequest + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + msg, err := server.DeleteScript(ctx, &protoReq) + return msg, metadata, err +} + +func request_Scripts_GenerateScript_0(ctx context.Context, marshaler runtime.Marshaler, client ScriptsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GenerateScriptRequest + metadata runtime.ServerMetadata + err error + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + val, ok := pathParams["script_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "script_id") + } + protoReq.ScriptId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "script_id", err) + } + msg, err := client.GenerateScript(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Scripts_GenerateScript_0(ctx context.Context, marshaler runtime.Marshaler, server ScriptsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GenerateScriptRequest + metadata runtime.ServerMetadata + err error + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + val, ok := pathParams["script_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "script_id") + } + protoReq.ScriptId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "script_id", err) + } + msg, err := server.GenerateScript(ctx, &protoReq) + return msg, metadata, err +} + +// RegisterScriptsHandlerServer registers the http handlers for service Scripts to "mux". +// UnaryRPC :call ScriptsServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterScriptsHandlerFromEndpoint instead. +// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. +func RegisterScriptsHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ScriptsServer) error { + mux.Handle(http.MethodGet, pattern_Scripts_ListScripts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/Superplane.Scripts.Scripts/ListScripts", runtime.WithHTTPPathPattern("/api/v1/scripts")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Scripts_ListScripts_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_ListScripts_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodGet, pattern_Scripts_DescribeScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/Superplane.Scripts.Scripts/DescribeScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Scripts_DescribeScript_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_DescribeScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodPost, pattern_Scripts_CreateScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/Superplane.Scripts.Scripts/CreateScript", runtime.WithHTTPPathPattern("/api/v1/scripts")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Scripts_CreateScript_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_CreateScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodPatch, pattern_Scripts_UpdateScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/Superplane.Scripts.Scripts/UpdateScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Scripts_UpdateScript_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_UpdateScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodDelete, pattern_Scripts_DeleteScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/Superplane.Scripts.Scripts/DeleteScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Scripts_DeleteScript_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_DeleteScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodPost, pattern_Scripts_GenerateScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/Superplane.Scripts.Scripts/GenerateScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{script_id}/generate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Scripts_GenerateScript_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_GenerateScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + return nil +} + +// RegisterScriptsHandlerFromEndpoint is same as RegisterScriptsHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterScriptsHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.NewClient(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + return RegisterScriptsHandler(ctx, mux, conn) +} + +// RegisterScriptsHandler registers the http handlers for service Scripts to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterScriptsHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterScriptsHandlerClient(ctx, mux, NewScriptsClient(conn)) +} + +// RegisterScriptsHandlerClient registers the http handlers for service Scripts +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ScriptsClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ScriptsClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ScriptsClient" to call the correct interceptors. This client ignores the HTTP middlewares. +func RegisterScriptsHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ScriptsClient) error { + mux.Handle(http.MethodGet, pattern_Scripts_ListScripts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/Superplane.Scripts.Scripts/ListScripts", runtime.WithHTTPPathPattern("/api/v1/scripts")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Scripts_ListScripts_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_ListScripts_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodGet, pattern_Scripts_DescribeScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/Superplane.Scripts.Scripts/DescribeScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Scripts_DescribeScript_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_DescribeScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodPost, pattern_Scripts_CreateScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/Superplane.Scripts.Scripts/CreateScript", runtime.WithHTTPPathPattern("/api/v1/scripts")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Scripts_CreateScript_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_CreateScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodPatch, pattern_Scripts_UpdateScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/Superplane.Scripts.Scripts/UpdateScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Scripts_UpdateScript_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_UpdateScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodDelete, pattern_Scripts_DeleteScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/Superplane.Scripts.Scripts/DeleteScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Scripts_DeleteScript_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_DeleteScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodPost, pattern_Scripts_GenerateScript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/Superplane.Scripts.Scripts/GenerateScript", runtime.WithHTTPPathPattern("/api/v1/scripts/{script_id}/generate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Scripts_GenerateScript_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Scripts_GenerateScript_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil +} + +var ( + pattern_Scripts_ListScripts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "scripts"}, "")) + pattern_Scripts_DescribeScript_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "scripts", "id"}, "")) + pattern_Scripts_CreateScript_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "scripts"}, "")) + pattern_Scripts_UpdateScript_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "scripts", "id"}, "")) + pattern_Scripts_DeleteScript_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "scripts", "id"}, "")) + pattern_Scripts_GenerateScript_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "scripts", "script_id", "generate"}, "")) +) + +var ( + forward_Scripts_ListScripts_0 = runtime.ForwardResponseMessage + forward_Scripts_DescribeScript_0 = runtime.ForwardResponseMessage + forward_Scripts_CreateScript_0 = runtime.ForwardResponseMessage + forward_Scripts_UpdateScript_0 = runtime.ForwardResponseMessage + forward_Scripts_DeleteScript_0 = runtime.ForwardResponseMessage + forward_Scripts_GenerateScript_0 = runtime.ForwardResponseMessage +) diff --git a/pkg/protos/scripts/scripts_grpc.pb.go b/pkg/protos/scripts/scripts_grpc.pb.go new file mode 100644 index 0000000000..89dd19d0f5 --- /dev/null +++ b/pkg/protos/scripts/scripts_grpc.pb.go @@ -0,0 +1,309 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.0 +// - protoc v3.15.8 +// source: scripts.proto + +package scripts + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Scripts_ListScripts_FullMethodName = "/Superplane.Scripts.Scripts/ListScripts" + Scripts_DescribeScript_FullMethodName = "/Superplane.Scripts.Scripts/DescribeScript" + Scripts_CreateScript_FullMethodName = "/Superplane.Scripts.Scripts/CreateScript" + Scripts_UpdateScript_FullMethodName = "/Superplane.Scripts.Scripts/UpdateScript" + Scripts_DeleteScript_FullMethodName = "/Superplane.Scripts.Scripts/DeleteScript" + Scripts_GenerateScript_FullMethodName = "/Superplane.Scripts.Scripts/GenerateScript" +) + +// ScriptsClient is the client API for Scripts service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ScriptsClient interface { + ListScripts(ctx context.Context, in *ListScriptsRequest, opts ...grpc.CallOption) (*ListScriptsResponse, error) + DescribeScript(ctx context.Context, in *DescribeScriptRequest, opts ...grpc.CallOption) (*DescribeScriptResponse, error) + CreateScript(ctx context.Context, in *CreateScriptRequest, opts ...grpc.CallOption) (*CreateScriptResponse, error) + UpdateScript(ctx context.Context, in *UpdateScriptRequest, opts ...grpc.CallOption) (*UpdateScriptResponse, error) + DeleteScript(ctx context.Context, in *DeleteScriptRequest, opts ...grpc.CallOption) (*DeleteScriptResponse, error) + GenerateScript(ctx context.Context, in *GenerateScriptRequest, opts ...grpc.CallOption) (*GenerateScriptResponse, error) +} + +type scriptsClient struct { + cc grpc.ClientConnInterface +} + +func NewScriptsClient(cc grpc.ClientConnInterface) ScriptsClient { + return &scriptsClient{cc} +} + +func (c *scriptsClient) ListScripts(ctx context.Context, in *ListScriptsRequest, opts ...grpc.CallOption) (*ListScriptsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListScriptsResponse) + err := c.cc.Invoke(ctx, Scripts_ListScripts_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scriptsClient) DescribeScript(ctx context.Context, in *DescribeScriptRequest, opts ...grpc.CallOption) (*DescribeScriptResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DescribeScriptResponse) + err := c.cc.Invoke(ctx, Scripts_DescribeScript_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scriptsClient) CreateScript(ctx context.Context, in *CreateScriptRequest, opts ...grpc.CallOption) (*CreateScriptResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateScriptResponse) + err := c.cc.Invoke(ctx, Scripts_CreateScript_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scriptsClient) UpdateScript(ctx context.Context, in *UpdateScriptRequest, opts ...grpc.CallOption) (*UpdateScriptResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateScriptResponse) + err := c.cc.Invoke(ctx, Scripts_UpdateScript_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scriptsClient) DeleteScript(ctx context.Context, in *DeleteScriptRequest, opts ...grpc.CallOption) (*DeleteScriptResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteScriptResponse) + err := c.cc.Invoke(ctx, Scripts_DeleteScript_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scriptsClient) GenerateScript(ctx context.Context, in *GenerateScriptRequest, opts ...grpc.CallOption) (*GenerateScriptResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GenerateScriptResponse) + err := c.cc.Invoke(ctx, Scripts_GenerateScript_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ScriptsServer is the server API for Scripts service. +// All implementations should embed UnimplementedScriptsServer +// for forward compatibility. +type ScriptsServer interface { + ListScripts(context.Context, *ListScriptsRequest) (*ListScriptsResponse, error) + DescribeScript(context.Context, *DescribeScriptRequest) (*DescribeScriptResponse, error) + CreateScript(context.Context, *CreateScriptRequest) (*CreateScriptResponse, error) + UpdateScript(context.Context, *UpdateScriptRequest) (*UpdateScriptResponse, error) + DeleteScript(context.Context, *DeleteScriptRequest) (*DeleteScriptResponse, error) + GenerateScript(context.Context, *GenerateScriptRequest) (*GenerateScriptResponse, error) +} + +// UnimplementedScriptsServer should be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedScriptsServer struct{} + +func (UnimplementedScriptsServer) ListScripts(context.Context, *ListScriptsRequest) (*ListScriptsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListScripts not implemented") +} +func (UnimplementedScriptsServer) DescribeScript(context.Context, *DescribeScriptRequest) (*DescribeScriptResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DescribeScript not implemented") +} +func (UnimplementedScriptsServer) CreateScript(context.Context, *CreateScriptRequest) (*CreateScriptResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateScript not implemented") +} +func (UnimplementedScriptsServer) UpdateScript(context.Context, *UpdateScriptRequest) (*UpdateScriptResponse, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateScript not implemented") +} +func (UnimplementedScriptsServer) DeleteScript(context.Context, *DeleteScriptRequest) (*DeleteScriptResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteScript not implemented") +} +func (UnimplementedScriptsServer) GenerateScript(context.Context, *GenerateScriptRequest) (*GenerateScriptResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GenerateScript not implemented") +} +func (UnimplementedScriptsServer) testEmbeddedByValue() {} + +// UnsafeScriptsServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ScriptsServer will +// result in compilation errors. +type UnsafeScriptsServer interface { + mustEmbedUnimplementedScriptsServer() +} + +func RegisterScriptsServer(s grpc.ServiceRegistrar, srv ScriptsServer) { + // If the following call panics, it indicates UnimplementedScriptsServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Scripts_ServiceDesc, srv) +} + +func _Scripts_ListScripts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListScriptsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScriptsServer).ListScripts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Scripts_ListScripts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScriptsServer).ListScripts(ctx, req.(*ListScriptsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Scripts_DescribeScript_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DescribeScriptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScriptsServer).DescribeScript(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Scripts_DescribeScript_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScriptsServer).DescribeScript(ctx, req.(*DescribeScriptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Scripts_CreateScript_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateScriptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScriptsServer).CreateScript(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Scripts_CreateScript_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScriptsServer).CreateScript(ctx, req.(*CreateScriptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Scripts_UpdateScript_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateScriptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScriptsServer).UpdateScript(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Scripts_UpdateScript_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScriptsServer).UpdateScript(ctx, req.(*UpdateScriptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Scripts_DeleteScript_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteScriptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScriptsServer).DeleteScript(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Scripts_DeleteScript_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScriptsServer).DeleteScript(ctx, req.(*DeleteScriptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Scripts_GenerateScript_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateScriptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScriptsServer).GenerateScript(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Scripts_GenerateScript_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScriptsServer).GenerateScript(ctx, req.(*GenerateScriptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Scripts_ServiceDesc is the grpc.ServiceDesc for Scripts service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Scripts_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "Superplane.Scripts.Scripts", + HandlerType: (*ScriptsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListScripts", + Handler: _Scripts_ListScripts_Handler, + }, + { + MethodName: "DescribeScript", + Handler: _Scripts_DescribeScript_Handler, + }, + { + MethodName: "CreateScript", + Handler: _Scripts_CreateScript_Handler, + }, + { + MethodName: "UpdateScript", + Handler: _Scripts_UpdateScript_Handler, + }, + { + MethodName: "DeleteScript", + Handler: _Scripts_DeleteScript_Handler, + }, + { + MethodName: "GenerateScript", + Handler: _Scripts_GenerateScript_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "scripts.proto", +} diff --git a/pkg/protos/triggers/triggers.pb.go b/pkg/protos/triggers/triggers.pb.go index d5acaf6032..25882f83c3 100644 --- a/pkg/protos/triggers/triggers.pb.go +++ b/pkg/protos/triggers/triggers.pb.go @@ -202,6 +202,7 @@ type Trigger struct { Color string `protobuf:"bytes,5,opt,name=color,proto3" json:"color,omitempty"` Configuration []*configuration.Field `protobuf:"bytes,6,rep,name=configuration,proto3" json:"configuration,omitempty"` ExampleData *_struct.Struct `protobuf:"bytes,7,opt,name=example_data,json=exampleData,proto3" json:"example_data,omitempty"` + Source string `protobuf:"bytes,8,opt,name=source,proto3" json:"source,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -285,6 +286,13 @@ func (x *Trigger) GetExampleData() *_struct.Struct { return nil } +func (x *Trigger) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + var File_triggers_proto protoreflect.FileDescriptor const file_triggers_proto_rawDesc = "" + @@ -296,7 +304,7 @@ const file_triggers_proto_rawDesc = "" + "\x16DescribeTriggerRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\"Q\n" + "\x17DescribeTriggerResponse\x126\n" + - "\atrigger\x18\x01 \x01(\v2\x1c.Superplane.Triggers.TriggerR\atrigger\"\x82\x02\n" + + "\atrigger\x18\x01 \x01(\v2\x1c.Superplane.Triggers.TriggerR\atrigger\"\x9a\x02\n" + "\aTrigger\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + "\x05label\x18\x02 \x01(\tR\x05label\x12 \n" + @@ -304,7 +312,8 @@ const file_triggers_proto_rawDesc = "" + "\x04icon\x18\x04 \x01(\tR\x04icon\x12\x14\n" + "\x05color\x18\x05 \x01(\tR\x05color\x12E\n" + "\rconfiguration\x18\x06 \x03(\v2\x1f.Superplane.Configuration.FieldR\rconfiguration\x12:\n" + - "\fexample_data\x18\a \x01(\v2\x17.google.protobuf.StructR\vexampleData2\x9c\x03\n" + + "\fexample_data\x18\a \x01(\v2\x17.google.protobuf.StructR\vexampleData\x12\x16\n" + + "\x06source\x18\b \x01(\tR\x06source2\x9c\x03\n" + "\bTriggers\x12\xc2\x01\n" + "\fListTriggers\x12(.Superplane.Triggers.ListTriggersRequest\x1a).Superplane.Triggers.ListTriggersResponse\"]\x92AB\n" + "\aTrigger\x12\rList triggers\x1a(Returns a list of all available triggers\x82\xd3\xe4\x93\x02\x12\x12\x10/api/v1/triggers\x12\xca\x01\n" + diff --git a/pkg/public/server.go b/pkg/public/server.go index 00ba9d9e3a..a775bd0b03 100644 --- a/pkg/public/server.go +++ b/pkg/public/server.go @@ -42,6 +42,7 @@ import ( pbMe "github.com/superplanehq/superplane/pkg/protos/me" pbOrg "github.com/superplanehq/superplane/pkg/protos/organizations" pbRoles "github.com/superplanehq/superplane/pkg/protos/roles" + pbScripts "github.com/superplanehq/superplane/pkg/protos/scripts" pbSecret "github.com/superplanehq/superplane/pkg/protos/secrets" pbServiceAccounts "github.com/superplanehq/superplane/pkg/protos/service_accounts" pbTriggers "github.com/superplanehq/superplane/pkg/protos/triggers" @@ -239,6 +240,11 @@ func (s *Server) RegisterGRPCGateway(grpcServerAddr string) error { return err } + err = pbScripts.RegisterScriptsHandlerFromEndpoint(ctx, grpcGatewayMux, grpcServerAddr, opts) + if err != nil { + return err + } + // Public health check s.Router.HandleFunc("/api/v1/canvases/is-alive", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) @@ -265,6 +271,7 @@ func (s *Server) RegisterGRPCGateway(grpcServerAddr string) error { s.Router.PathPrefix("/api/v1/widgets").Handler(protectedGRPCHandler) s.Router.PathPrefix("/api/v1/blueprints").Handler(protectedGRPCHandler) s.Router.PathPrefix("/api/v1/service-accounts").Handler(protectedGRPCHandler) + s.Router.PathPrefix("/api/v1/scripts").Handler(protectedGRPCHandler) s.Router.PathPrefix("/api/v1/workflows").Handler(protectedGRPCHandler) return nil diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index 9d27b68c61..831ccef574 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -137,18 +137,18 @@ func (r *Registry) ListTriggers() []core.Trigger { } func (r *Registry) GetTrigger(name string) (core.Trigger, error) { + // Check direct registration first (covers both simple and dotted plugin names) + if trigger, ok := r.Triggers[name]; ok { + return trigger, nil + } + parts := strings.SplitN(name, ".", 2) if len(parts) > 2 { return nil, fmt.Errorf("invalid trigger name: %s", name) } if len(parts) == 1 { - trigger, ok := r.Triggers[name] - if !ok { - return nil, fmt.Errorf("trigger %s not registered", name) - } - - return trigger, nil + return nil, fmt.Errorf("trigger %s not registered", name) } return r.GetIntegrationTrigger(parts[0], name) @@ -168,18 +168,18 @@ func (r *Registry) ListComponents() []core.Component { } func (r *Registry) GetComponent(name string) (core.Component, error) { + // Check direct registration first (covers both simple and dotted plugin names) + if component, ok := r.Components[name]; ok { + return component, nil + } + parts := strings.SplitN(name, ".", 2) if len(parts) > 2 { return nil, fmt.Errorf("invalid component name: %s", name) } if len(parts) == 1 { - component, ok := r.Components[name] - if !ok { - return nil, fmt.Errorf("component %s not registered", name) - } - - return component, nil + return nil, fmt.Errorf("component %s not registered", name) } return r.GetIntegrationComponent(parts[0], name) diff --git a/pkg/server/server.go b/pkg/server/server.go index 40728a2079..9c09b1e6a4 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -4,17 +4,21 @@ import ( "context" "fmt" "os" + "os/signal" "strconv" "strings" + "syscall" "time" log "github.com/sirupsen/logrus" + "github.com/superplanehq/superplane/pkg/ai" "github.com/superplanehq/superplane/pkg/authorization" "github.com/superplanehq/superplane/pkg/config" "github.com/superplanehq/superplane/pkg/crypto" grpc "github.com/superplanehq/superplane/pkg/grpc" "github.com/superplanehq/superplane/pkg/jwt" "github.com/superplanehq/superplane/pkg/oidc" + "github.com/superplanehq/superplane/pkg/plugins" "github.com/superplanehq/superplane/pkg/public" registry "github.com/superplanehq/superplane/pkg/registry" "github.com/superplanehq/superplane/pkg/services" @@ -189,9 +193,9 @@ func startEmailConsumersWithService(rabbitMQURL string, emailService services.Em go notificationEmailConsumer.Start() } -func startInternalAPI(baseURL, webhooksBaseURL, basePath string, encryptor crypto.Encryptor, authService authorization.Authorization, registry *registry.Registry, oidcProvider oidc.Provider) { +func startInternalAPI(baseURL, webhooksBaseURL, basePath string, encryptor crypto.Encryptor, authService authorization.Authorization, registry *registry.Registry, oidcProvider oidc.Provider, aiClient *ai.Client, pluginManager grpc.PluginActivator) { log.Println("Starting Internal API") - grpc.RunServer(baseURL, webhooksBaseURL, basePath, encryptor, authService, registry, oidcProvider, lookupInternalAPIPort()) + grpc.RunServer(baseURL, webhooksBaseURL, basePath, encryptor, authService, registry, oidcProvider, aiClient, pluginManager, lookupInternalAPIPort()) } func startPublicAPI(baseURL, basePath string, encryptor crypto.Encryptor, registry *registry.Registry, jwtSigner *jwt.Signer, oidcProvider oidc.Provider, authService authorization.Authorization) { @@ -372,12 +376,47 @@ func Start() { templates.Setup(registry) + pluginsDir := os.Getenv("SUPERPLANE_PLUGINS_DIR") + if pluginsDir == "" { + pluginsDir = "plugins" + } + + pluginManager, err := plugins.NewManager(pluginsDir, registry) + if err != nil { + log.Infof("Plugin system (.spx): %v", err) + } else { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGHUP) + go func() { + for range sigCh { + log.Info("Received SIGHUP, reloading plugins") + pluginManager.Reload() + } + }() + } + + if pluginManager != nil { + if err := pluginManager.LoadScriptsFromDB(); err != nil { + log.Warnf("Failed to load scripts from DB: %v", err) + } + } + if os.Getenv("START_PUBLIC_API") == "yes" { go startPublicAPI(baseURL, basePath, encryptorInstance, registry, jwtSigner, oidcProvider, authService) } + var aiClient *ai.Client + if key := os.Getenv("OPENAI_API_KEY"); key != "" { + aiClient = ai.NewClient(key) + log.Info("AI script generation enabled") + } + if os.Getenv("START_INTERNAL_API") == "yes" { - go startInternalAPI(baseURL, webhooksBaseURL, basePath, encryptorInstance, authService, registry, oidcProvider) + var activator grpc.PluginActivator + if pluginManager != nil { + activator = pluginManager + } + go startInternalAPI(baseURL, webhooksBaseURL, basePath, encryptorInstance, authService, registry, oidcProvider, aiClient, activator) } startWorkers(encryptorInstance, registry, oidcProvider, baseURL, authService) diff --git a/plugin-host/package-lock.json b/plugin-host/package-lock.json new file mode 100644 index 0000000000..11de76a722 --- /dev/null +++ b/plugin-host/package-lock.json @@ -0,0 +1,47 @@ +{ + "name": "@superplane/plugin-host", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@superplane/plugin-host", + "version": "1.0.0", + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + } + }, + "node_modules/@types/node": { + "version": "22.19.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", + "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/plugin-host/package.json b/plugin-host/package.json new file mode 100644 index 0000000000..06f246b8f1 --- /dev/null +++ b/plugin-host/package.json @@ -0,0 +1,15 @@ +{ + "name": "@superplane/plugin-host", + "version": "1.0.0", + "private": true, + "description": "SuperPlane Plugin Host - runs plugins in an isolated Node.js process", + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "dev": "tsc --watch" + }, + "devDependencies": { + "typescript": "^5.8.0", + "@types/node": "^22.0.0" + } +} diff --git a/plugin-host/src/index.ts b/plugin-host/src/index.ts new file mode 100644 index 0000000000..2b614e5064 --- /dev/null +++ b/plugin-host/src/index.ts @@ -0,0 +1,437 @@ +import * as path from "path"; +import * as vm from "vm"; +import { RpcTransport } from "./rpc"; +import * as sdk from "./sdk"; +import { + PluginContextImpl, + buildExecutionContext, + buildSetupContext, + buildTriggerSetupContext, + buildWebhookContext, + buildIntegrationSyncContext, + buildIntegrationRequestContext, + buildIntegrationCleanupContext, + buildWebhookHandlerSetupContext, + buildWebhookHandlerCleanupContext, +} from "./sdk"; + +/** + * Converts ES module syntax to CommonJS so scripts can run inside vm.compileFunction. + * Handles: import, export function, export async function, export const/let/var, export default. + */ +function esmToCjs(source: string): string { + const exportedNames: string[] = []; + + let result = source + // import { a, b } from "mod" → const { a, b } = require("mod") + .replace(/\bimport\s+\{([^}]+)\}\s+from\s+["']([^"']+)["']\s*;?/g, + (_match, names, mod) => `const {${names}} = require("${mod}");`) + // import X from "mod" → const X = require("mod") + .replace(/\bimport\s+(\w+)\s+from\s+["']([^"']+)["']\s*;?/g, + (_match, name, mod) => `const ${name} = require("${mod}");`) + // import * as X from "mod" → const X = require("mod") + .replace(/\bimport\s+\*\s+as\s+(\w+)\s+from\s+["']([^"']+)["']\s*;?/g, + (_match, name, mod) => `const ${name} = require("${mod}");`) + // export async function name(...) + .replace(/\bexport\s+async\s+function\s+(\w+)/g, (_match, name) => { + exportedNames.push(name); + return `async function ${name}`; + }) + // export function name(...) + .replace(/\bexport\s+function\s+(\w+)/g, (_match, name) => { + exportedNames.push(name); + return `function ${name}`; + }) + // export const/let/var name + .replace(/\bexport\s+(const|let|var)\s+(\w+)/g, (_match, kind, name) => { + exportedNames.push(name); + return `${kind} ${name}`; + }) + // export default (treat as module.exports directly) + .replace(/\bexport\s+default\s+/g, "module.exports = "); + + if (exportedNames.length > 0) { + result += "\n" + exportedNames.map((n) => `module.exports.${n} = ${n};`).join("\n") + "\n"; + } + + return result; +} + +interface LoadedPlugin { + id: string; + path: string; + context: PluginContextImpl; + deactivate?: () => void | Promise; +} + +const plugins = new Map(); + +// Pre-populate the require cache so that `require("@superplane/sdk")` +// resolves to the SDK bundled in the Plugin Host. +// This avoids monkey-patching Module._resolveFilename which is +// read-only in Node.js v22+. +const sdkCacheKey = require.resolve("./sdk"); +require.cache["@superplane/sdk"] = require.cache[sdkCacheKey]!; + +const rpc = new RpcTransport(async (method: string, params: any) => { + switch (method) { + case "plugin/activate": + return handleActivate(params); + + case "plugin/deactivate": + return handleDeactivate(params); + + case "plugin/activateInline": + return handleActivateInline(params); + + default: { + if (method.startsWith("component/")) { + return handleComponentCall(method, params); + } + if (method.startsWith("trigger/")) { + return handleTriggerCall(method, params); + } + if (method.startsWith("integration/")) { + return handleIntegrationCall(method, params); + } + if (method.startsWith("webhookHandler/")) { + return handleWebhookHandlerCall(method, params); + } + + throw new Error(`Unknown method: ${method}`); + } + } +}); + +async function handleActivate(params: { + pluginId: string; + pluginPath: string; +}): Promise { + const { pluginId, pluginPath } = params; + + if (plugins.has(pluginId)) { + return; + } + + const extensionPath = path.resolve(pluginPath, "extension.js"); + const context = new PluginContextImpl(pluginId, rpc); + + let pluginModule: any; + try { + pluginModule = require(extensionPath); + } catch (err: any) { + throw new Error( + `Failed to load plugin ${pluginId}: ${err.message}` + ); + } + + if (typeof pluginModule.activate !== "function") { + throw new Error( + `Plugin ${pluginId} does not export an activate() function` + ); + } + + await pluginModule.activate(context); + + const plugin: LoadedPlugin = { + id: pluginId, + path: pluginPath, + context, + deactivate: + typeof pluginModule.deactivate === "function" + ? pluginModule.deactivate + : undefined, + }; + + plugins.set(pluginId, plugin); +} + +async function handleActivateInline(params: { + pluginId: string; + source: string; + manifest: any; +}): Promise<{ components: any[]; triggers: any[] }> { + const { pluginId, source } = params; + + if (plugins.has(pluginId)) { + await handleDeactivate({ pluginId }); + } + + const context = new PluginContextImpl(pluginId, rpc); + + let pluginModule: any; + try { + const cjsSource = esmToCjs(source); + const moduleExports: any = {}; + const moduleObj = { exports: moduleExports }; + + const scriptRequire = (id: string) => { + if (id === "@superplane/sdk") return sdk; + return require(id); + }; + + const wrappedFn = vm.compileFunction(cjsSource, ["require", "module", "exports"], { + filename: `${pluginId}.js`, + }); + wrappedFn(scriptRequire, moduleObj, moduleExports); + pluginModule = moduleObj.exports; + } catch (err: any) { + throw new Error(`Failed to evaluate script ${pluginId}: ${err.message}`); + } + + if (typeof pluginModule.activate !== "function") { + throw new Error(`Script ${pluginId} does not export an activate() function`); + } + + await pluginModule.activate(context); + + plugins.set(pluginId, { + id: pluginId, + path: "", + context, + deactivate: + typeof pluginModule.deactivate === "function" ? pluginModule.deactivate : undefined, + }); + + return { + components: context.components.getRegisteredMetadata(), + triggers: context.triggers.getRegisteredMetadata(), + }; +} + +async function handleDeactivate(params: { + pluginId: string; +}): Promise { + const plugin = plugins.get(params.pluginId); + if (!plugin) return; + + if (plugin.deactivate) { + await plugin.deactivate(); + } + + // Dispose all tracked subscriptions + for (const sub of plugin.context.subscriptions) { + sub.dispose(); + } + + plugins.delete(params.pluginId); +} + +async function handleComponentCall( + method: string, + params: { pluginId: string; component: string; context: any } +): Promise { + const plugin = plugins.get(params.pluginId); + if (!plugin) { + throw new Error(`Plugin ${params.pluginId} is not activated`); + } + + const handler = plugin.context.components.getHandler(params.component); + if (!handler) { + throw new Error( + `Component handler ${params.component} not registered by plugin ${params.pluginId}` + ); + } + + const action = method.replace("component/", ""); + + switch (action) { + case "setup": { + const ctx = buildSetupContext(params.context, rpc, params.pluginId); + await handler.setup?.(ctx); + return null; + } + + case "execute": { + const { ctx, getResult } = buildExecutionContext( + params.context, + rpc, + params.pluginId + ); + await handler.execute(ctx); + return getResult(); + } + + case "cancel": { + const { ctx } = buildExecutionContext( + params.context, + rpc, + params.pluginId + ); + await handler.cancel?.(ctx); + return null; + } + + case "cleanup": { + const ctx = buildSetupContext(params.context, rpc, params.pluginId); + await handler.cleanup?.(ctx); + return null; + } + + default: + throw new Error(`Unknown component action: ${action}`); + } +} + +async function handleTriggerCall( + method: string, + params: { pluginId: string; trigger: string; context: any } +): Promise { + const plugin = plugins.get(params.pluginId); + if (!plugin) { + throw new Error(`Plugin ${params.pluginId} is not activated`); + } + + const handler = plugin.context.triggers.getHandler(params.trigger); + if (!handler) { + throw new Error( + `Trigger handler ${params.trigger} not registered by plugin ${params.pluginId}` + ); + } + + const action = method.replace("trigger/", ""); + + switch (action) { + case "setup": { + const ctx = buildTriggerSetupContext( + params.context, + rpc, + params.pluginId + ); + await handler.setup?.(ctx); + return null; + } + + case "handleWebhook": { + const ctx = buildWebhookContext(params.context, rpc, params.pluginId); + const result = await handler.handleWebhook?.(ctx); + return result ?? { status: 200 }; + } + + case "cleanup": { + const ctx = buildTriggerSetupContext( + params.context, + rpc, + params.pluginId + ); + await handler.cleanup?.(ctx); + return null; + } + + default: + throw new Error(`Unknown trigger action: ${action}`); + } +} + +async function handleIntegrationCall( + method: string, + params: { pluginId: string; integration: string; context: any } +): Promise { + const plugin = plugins.get(params.pluginId); + if (!plugin) { + throw new Error(`Plugin ${params.pluginId} is not activated`); + } + + const handler = plugin.context.integrations.getHandler(params.integration); + if (!handler) { + throw new Error( + `Integration handler ${params.integration} not registered by plugin ${params.pluginId}` + ); + } + + const action = method.replace("integration/", ""); + + switch (action) { + case "sync": { + const ctx = buildIntegrationSyncContext( + params.context, + rpc, + params.pluginId + ); + await handler.sync?.(ctx); + return null; + } + + case "handleRequest": { + const ctx = buildIntegrationRequestContext( + params.context, + rpc, + params.pluginId + ); + return (await handler.handleRequest?.(ctx)) ?? null; + } + + case "cleanup": { + const ctx = buildIntegrationCleanupContext( + params.context, + rpc, + params.pluginId + ); + await handler.cleanup?.(ctx); + return null; + } + + default: + throw new Error(`Unknown integration action: ${action}`); + } +} + +async function handleWebhookHandlerCall( + method: string, + params: { pluginId: string; integration: string; context: any } +): Promise { + const plugin = plugins.get(params.pluginId); + if (!plugin) { + throw new Error(`Plugin ${params.pluginId} is not activated`); + } + + const handler = plugin.context.integrations.getHandler(params.integration); + if (!handler?.webhookHandler) { + throw new Error( + `Webhook handler not registered for integration ${params.integration} by plugin ${params.pluginId}` + ); + } + + const action = method.replace("webhookHandler/", ""); + + switch (action) { + case "setup": { + const ctx = buildWebhookHandlerSetupContext( + params.context, + rpc, + params.pluginId + ); + return await handler.webhookHandler.setup(ctx); + } + + case "cleanup": { + const ctx = buildWebhookHandlerCleanupContext( + params.context, + rpc, + params.pluginId + ); + await handler.webhookHandler.cleanup(ctx); + return null; + } + + case "compareConfig": { + return await handler.webhookHandler.compareConfig( + params.context.a, + params.context.b + ); + } + + default: + throw new Error(`Unknown webhookHandler action: ${action}`); + } +} + +// Catch unhandled errors to prevent crashing the Plugin Host +process.on("uncaughtException", (err) => { + process.stderr.write(`Plugin Host uncaught exception: ${err.message}\n`); + process.stderr.write(`${err.stack}\n`); +}); + +process.on("unhandledRejection", (reason) => { + process.stderr.write(`Plugin Host unhandled rejection: ${reason}\n`); +}); diff --git a/plugin-host/src/rpc.ts b/plugin-host/src/rpc.ts new file mode 100644 index 0000000000..8696d19fa0 --- /dev/null +++ b/plugin-host/src/rpc.ts @@ -0,0 +1,142 @@ +import * as readline from "readline"; + +export interface JsonRpcRequest { + jsonrpc: "2.0"; + id?: number; + method: string; + params?: any; +} + +export interface JsonRpcResponse { + jsonrpc: "2.0"; + id: number; + result?: any; + error?: JsonRpcError; +} + +export interface JsonRpcError { + code: number; + message: string; + data?: any; +} + +type RequestHandler = ( + method: string, + params: any +) => Promise; + +/** + * Bidirectional JSON-RPC 2.0 transport over stdin/stdout. + * + * - Receives requests from the Go server on stdin + * - Sends responses back on stdout + * - Can also send requests TO the Go server and receive responses + */ +export class RpcTransport { + private nextId = 1; + private pendingRequests = new Map< + number, + { resolve: (value: any) => void; reject: (error: Error) => void } + >(); + private requestHandler: RequestHandler; + private rl: readline.Interface; + + constructor(requestHandler: RequestHandler) { + this.requestHandler = requestHandler; + + this.rl = readline.createInterface({ + input: process.stdin, + terminal: false, + }); + + this.rl.on("line", (line: string) => { + this.handleLine(line); + }); + + this.rl.on("close", () => { + process.exit(0); + }); + } + + private async handleLine(line: string): Promise { + let msg: any; + try { + msg = JSON.parse(line); + } catch { + return; + } + + // If it has a method, it's a request (from Go to us) + if (msg.method) { + await this.handleIncomingRequest(msg); + return; + } + + // If it has an id and result/error, it's a response to one of our requests + if (msg.id !== undefined && (msg.result !== undefined || msg.error)) { + this.handleIncomingResponse(msg as JsonRpcResponse); + return; + } + } + + private async handleIncomingRequest(req: JsonRpcRequest): Promise { + try { + const result = await this.requestHandler(req.method, req.params); + if (req.id !== undefined) { + this.sendMessage({ + jsonrpc: "2.0", + id: req.id, + result: result ?? null, + }); + } + } catch (err: any) { + if (req.id !== undefined) { + this.sendMessage({ + jsonrpc: "2.0", + id: req.id, + error: { + code: -32000, + message: err.message || String(err), + }, + }); + } + } + } + + private handleIncomingResponse(resp: JsonRpcResponse): void { + const pending = this.pendingRequests.get(resp.id); + if (!pending) return; + + this.pendingRequests.delete(resp.id); + + if (resp.error) { + pending.reject(new Error(resp.error.message)); + } else { + pending.resolve(resp.result); + } + } + + /** + * Send a request to the Go server and wait for a response. + * Used for context callbacks (secrets, http, metadata, etc.). + */ + async call(method: string, params?: any): Promise { + const id = this.nextId++; + + return new Promise((resolve, reject) => { + this.pendingRequests.set(id, { resolve, reject }); + + this.sendMessage({ + jsonrpc: "2.0", + id, + method, + params, + }); + }); + } + + private sendMessage(msg: any): void { + const line = JSON.stringify(msg); + process.stdout.write(line + "\n"); + } +} diff --git a/plugin-host/src/sdk.ts b/plugin-host/src/sdk.ts new file mode 100644 index 0000000000..9ae5dc523d --- /dev/null +++ b/plugin-host/src/sdk.ts @@ -0,0 +1,663 @@ +import type { RpcTransport } from "./rpc"; + +export interface Disposable { + dispose(): void; +} + +export interface Logger { + info(message: string, ...args: any[]): void; + warn(message: string, ...args: any[]): void; + error(message: string, ...args: any[]): void; + debug(message: string, ...args: any[]): void; +} + +export interface MetadataAccessor { + get(): Promise; + set(value: any): Promise; +} + +export interface HTTPOptions { + headers?: Record; + body?: string; + timeout?: number; +} + +export interface HTTPResponse { + status: number; + headers: Record; + body: any; +} + +export interface HTTPClient { + request( + method: string, + url: string, + options?: HTTPOptions + ): Promise; +} + +export interface SecretsAccessor { + getKey(secretName: string, keyName: string): Promise; +} + +export interface WebhookAccessor { + setup(): Promise; + getSecret(): Promise; +} + +export interface EventEmitter { + emit(payloadType: string, payload: any): void; +} + +// Component handler interfaces + +export interface SetupContext { + configuration: Record; + http: HTTPClient; + metadata: MetadataAccessor; + secrets: SecretsAccessor; + webhook: WebhookAccessor; + log: Logger; +} + +export interface ExecutionContext { + id: string; + workflowId: string; + organizationId: string; + nodeId: string; + sourceNodeId: string; + baseUrl: string; + input: any; + configuration: Record; + eval(expression: string): Promise>; + emit(channel: string, payloadType: string, data: any | any[]): void; + pass(): void; + fail(reason: string, message: string): void; + setKV(key: string, value: string): void; + metadata: MetadataAccessor; + nodeMetadata: MetadataAccessor; + http: HTTPClient; + secrets: SecretsAccessor; + integration: IntegrationContextAccessor; + log: Logger; +} + +export interface WebhookContext { + body: string; + headers: Record; + workflowId: string; + nodeId: string; + configuration: Record; + metadata: MetadataAccessor; + webhook: WebhookAccessor; + events: EventEmitter; + http: HTTPClient; + secrets: SecretsAccessor; + log: Logger; +} + +export interface TriggerSetupContext { + configuration: Record; + http: HTTPClient; + metadata: MetadataAccessor; + webhook: WebhookAccessor; + events: EventEmitter; + secrets: SecretsAccessor; + integration: IntegrationContextAccessor; + log: Logger; +} + +export interface ComponentHandler { + setup?(ctx: SetupContext): void | Promise; + execute(ctx: ExecutionContext): void | Promise; + cancel?(ctx: ExecutionContext): void | Promise; + cleanup?(ctx: SetupContext): void | Promise; +} + +export interface TriggerHandler { + setup?(ctx: TriggerSetupContext): void | Promise; + cleanup?(ctx: TriggerSetupContext): void | Promise; + handleWebhook?( + ctx: WebhookContext + ): { status: number } | Promise<{ status: number }>; +} + +export interface ComponentRegistry { + register(name: string, handler: ComponentHandler): Disposable; +} + +export interface TriggerRegistry { + register(name: string, handler: TriggerHandler): Disposable; +} + +// Integration handler interfaces + +export interface IntegrationContextAccessor { + getMetadata(): Promise; + setMetadata(value: any): Promise; + getConfig(name: string): Promise; + setSecret(name: string, value: string): Promise; + getSecrets(): Promise>; + newBrowserAction(action: { + description: string; + url: string; + method: string; + formFields?: Record; + }): Promise; + removeBrowserAction(): Promise; + ready(): Promise; + error(message: string): Promise; + requestWebhook(configuration: any): Promise; + id(): Promise; +} + +export interface IntegrationSyncContext { + configuration: Record; + baseUrl: string; + webhooksBaseUrl: string; + organizationId: string; + integration: IntegrationContextAccessor; + http: HTTPClient; + log: Logger; +} + +export interface IntegrationRequestContext { + request: { + method: string; + path: string; + query: Record; + headers: Record; + body: string; + }; + organizationId: string; + baseUrl: string; + webhooksBaseUrl: string; + integration: IntegrationContextAccessor; + http: HTTPClient; + log: Logger; +} + +export interface RequestResponse { + action: "redirect" | "json" | "error"; + url?: string; + status?: number; + body?: any; + message?: string; +} + +export interface IntegrationCleanupContext { + configuration: Record; + baseUrl: string; + organizationId: string; + integration: IntegrationContextAccessor; + http: HTTPClient; + log: Logger; +} + +export interface WebhookHandlerSetupContext { + webhookUrl: string; + webhookSecret: string; + configuration: any; + integration: IntegrationContextAccessor; + http: HTTPClient; + log: Logger; +} + +export interface WebhookHandlerCleanupContext { + webhookMetadata: any; + configuration: any; + integration: IntegrationContextAccessor; + http: HTTPClient; + log: Logger; +} + +export interface IntegrationHandler { + sync?(ctx: IntegrationSyncContext): Promise; + handleRequest?(ctx: IntegrationRequestContext): Promise; + cleanup?(ctx: IntegrationCleanupContext): Promise; + webhookHandler?: { + setup(ctx: WebhookHandlerSetupContext): Promise; + cleanup(ctx: WebhookHandlerCleanupContext): Promise; + compareConfig(a: any, b: any): Promise; + }; +} + +export interface IntegrationRegistry { + register(name: string, handler: IntegrationHandler): Disposable; +} + +export interface PluginContext { + components: ComponentRegistry; + triggers: TriggerRegistry; + integrations: IntegrationRegistry; + subscriptions: Disposable[]; + log: Logger; +} + +// Internal implementation + +export class PluginContextImpl implements PluginContext { + components: ComponentRegistryImpl; + triggers: TriggerRegistryImpl; + integrations: IntegrationRegistryImpl; + subscriptions: Disposable[] = []; + log: Logger; + + constructor( + private pluginId: string, + private rpc: RpcTransport + ) { + this.components = new ComponentRegistryImpl(); + this.triggers = new TriggerRegistryImpl(); + this.integrations = new IntegrationRegistryImpl(); + this.log = createLogger(pluginId, rpc); + } +} + +export class ComponentRegistryImpl implements ComponentRegistry { + private handlers = new Map>(); + + register(name: string, handler: ComponentHandler & Record): Disposable { + this.handlers.set(name, handler); + return { + dispose: () => this.handlers.delete(name), + }; + } + + getHandler(name: string): ComponentHandler | undefined { + return this.handlers.get(name); + } + + getRegisteredMetadata(): Array> { + const result: Array> = []; + for (const [name, handler] of this.handlers) { + result.push({ + name, + label: handler.label || name, + description: handler.description || "", + icon: handler.icon || "", + color: handler.color || "", + configuration: handler.configuration || [], + outputChannels: handler.outputChannels || [{ name: "default", label: "Default" }], + }); + } + return result; + } +} + +export class TriggerRegistryImpl implements TriggerRegistry { + private handlers = new Map>(); + + register(name: string, handler: TriggerHandler & Record): Disposable { + this.handlers.set(name, handler); + return { + dispose: () => this.handlers.delete(name), + }; + } + + getHandler(name: string): TriggerHandler | undefined { + return this.handlers.get(name); + } + + getRegisteredMetadata(): Array> { + const result: Array> = []; + for (const [name, handler] of this.handlers) { + result.push({ + name, + label: handler.label || name, + description: handler.description || "", + icon: handler.icon || "", + color: handler.color || "", + configuration: handler.configuration || [], + }); + } + return result; + } +} + +export class IntegrationRegistryImpl implements IntegrationRegistry { + private handlers = new Map(); + + register(name: string, handler: IntegrationHandler): Disposable { + this.handlers.set(name, handler); + return { + dispose: () => this.handlers.delete(name), + }; + } + + getHandler(name: string): IntegrationHandler | undefined { + return this.handlers.get(name); + } +} + +function createLogger(prefix: string, rpc: RpcTransport): Logger { + const log = (level: string, message: string) => { + rpc.call("ctx/log", { level, message: `[${prefix}] ${message}` }).catch( + () => {} + ); + }; + + return { + info: (msg) => log("info", msg), + warn: (msg) => log("warn", msg), + error: (msg) => log("error", msg), + debug: (msg) => log("debug", msg), + }; +} + +/** + * Build an ExecutionContext that records the plugin's action (emit/pass/fail) + * and proxies context operations back to Go via RPC. + */ +export function buildExecutionContext( + params: any, + rpc: RpcTransport, + pluginId: string +): { ctx: ExecutionContext; getResult: () => any } { + let result: any = null; + + const callId = params.callId || params.id || "unknown"; + + const ctx: ExecutionContext = { + id: params.id || "", + workflowId: params.workflowId || "", + organizationId: params.organizationId || "", + nodeId: params.nodeId || "", + sourceNodeId: params.sourceNodeId || "", + baseUrl: params.baseUrl || "", + input: params.input, + configuration: params.configuration || {}, + + emit(channel: string, payloadTypeOrData: any, data?: any) { + if (data === undefined && typeof payloadTypeOrData !== "string") { + result = { action: "emit", channel, payloadType: "json", data: payloadTypeOrData }; + } else { + result = { action: "emit", channel, payloadType: payloadTypeOrData, data }; + } + }, + + pass() { + result = { action: "pass" }; + }, + + fail(reason: string, message: string) { + result = { action: "fail", reason, message }; + }, + + setKV(key: string, value: string) { + result = { action: "setKV", key, value }; + }, + + async eval(expression: string) { + return rpc.call("ctx/eval", { contextId: callId, expression }); + }, + + metadata: buildMetadataAccessor(rpc, callId, "execution"), + nodeMetadata: buildMetadataAccessor(rpc, callId, "node"), + http: buildHTTPClient(rpc, callId), + secrets: buildSecretsAccessor(rpc, callId), + integration: buildIntegrationContextAccessor(rpc, callId), + log: createLogger(pluginId, rpc), + }; + + return { ctx, getResult: () => result }; +} + +export function buildSetupContext( + params: any, + rpc: RpcTransport, + pluginId: string +): SetupContext { + const callId = params.callId || "setup"; + return { + configuration: params.configuration || {}, + http: buildHTTPClient(rpc, callId), + metadata: buildMetadataAccessor(rpc, callId, "node"), + secrets: buildSecretsAccessor(rpc, callId), + webhook: buildWebhookAccessor(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +export function buildTriggerSetupContext( + params: any, + rpc: RpcTransport, + pluginId: string +): TriggerSetupContext { + const callId = params.callId || "setup"; + return { + configuration: params.configuration || {}, + http: buildHTTPClient(rpc, callId), + metadata: buildMetadataAccessor(rpc, callId, "node"), + webhook: buildWebhookAccessor(rpc, callId), + events: buildEventEmitter(rpc, callId), + secrets: buildSecretsAccessor(rpc, callId), + integration: buildIntegrationContextAccessor(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +export function buildWebhookContext( + params: any, + rpc: RpcTransport, + pluginId: string +): WebhookContext { + const callId = params.callId || "webhook"; + return { + body: params.body || "", + headers: params.headers || {}, + workflowId: params.workflowId || "", + nodeId: params.nodeId || "", + configuration: params.configuration || {}, + metadata: buildMetadataAccessor(rpc, callId, "node"), + webhook: buildWebhookAccessor(rpc, callId), + events: buildEventEmitter(rpc, callId), + http: buildHTTPClient(rpc, callId), + secrets: buildSecretsAccessor(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +function buildMetadataAccessor( + rpc: RpcTransport, + contextId: string, + scope: string +): MetadataAccessor { + return { + async get() { + return rpc.call("ctx/metadata.get", { contextId, scope }); + }, + async set(value: any) { + await rpc.call("ctx/metadata.set", { contextId, scope, value }); + }, + }; +} + +function buildHTTPClient(rpc: RpcTransport, contextId: string): HTTPClient { + return { + async request(method, url, options) { + return rpc.call("ctx/http.request", { + contextId, + method, + url, + options, + }); + }, + }; +} + +function buildSecretsAccessor( + rpc: RpcTransport, + contextId: string +): SecretsAccessor { + return { + async getKey(secretName, keyName) { + return rpc.call("ctx/secrets.getKey", { + contextId, + secretName, + keyName, + }); + }, + }; +} + +function buildWebhookAccessor( + rpc: RpcTransport, + contextId: string +): WebhookAccessor { + return { + async setup() { + return rpc.call("ctx/webhook.setup", { contextId }); + }, + async getSecret() { + return rpc.call("ctx/webhook.getSecret", { contextId }); + }, + }; +} + +function buildEventEmitter( + rpc: RpcTransport, + contextId: string +): EventEmitter { + return { + emit(payloadType: string, payload: any) { + rpc + .call("ctx/events.emit", { contextId, payloadType, payload }) + .catch(() => {}); + }, + }; +} + +function buildIntegrationContextAccessor( + rpc: RpcTransport, + contextId: string +): IntegrationContextAccessor { + return { + async getMetadata() { + return rpc.call("ctx/integration.getMetadata", { contextId }); + }, + async setMetadata(value: any) { + await rpc.call("ctx/integration.setMetadata", { contextId, value }); + }, + async getConfig(name: string) { + return rpc.call("ctx/integration.getConfig", { contextId, name }); + }, + async setSecret(name: string, value: string) { + await rpc.call("ctx/integration.setSecret", { contextId, name, value }); + }, + async getSecrets() { + return rpc.call("ctx/integration.getSecrets", { contextId }); + }, + async newBrowserAction(action) { + await rpc.call("ctx/integration.newBrowserAction", { + contextId, + ...action, + }); + }, + async removeBrowserAction() { + await rpc.call("ctx/integration.removeBrowserAction", { contextId }); + }, + async ready() { + await rpc.call("ctx/integration.ready", { contextId }); + }, + async error(message: string) { + await rpc.call("ctx/integration.error", { contextId, message }); + }, + async requestWebhook(configuration: any) { + await rpc.call("ctx/integration.requestWebhook", { + contextId, + configuration, + }); + }, + async id() { + return rpc.call("ctx/integration.id", { contextId }); + }, + }; +} + +export function buildIntegrationSyncContext( + params: any, + rpc: RpcTransport, + pluginId: string +): IntegrationSyncContext { + const callId = params.callId || "sync"; + return { + configuration: params.configuration || {}, + baseUrl: params.baseUrl || "", + webhooksBaseUrl: params.webhooksBaseUrl || "", + organizationId: params.organizationId || "", + integration: buildIntegrationContextAccessor(rpc, callId), + http: buildHTTPClient(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +export function buildIntegrationRequestContext( + params: any, + rpc: RpcTransport, + pluginId: string +): IntegrationRequestContext { + const callId = params.callId || "request"; + return { + request: params.request || { + method: "", + path: "", + query: {}, + headers: {}, + body: "", + }, + organizationId: params.organizationId || "", + baseUrl: params.baseUrl || "", + webhooksBaseUrl: params.webhooksBaseUrl || "", + integration: buildIntegrationContextAccessor(rpc, callId), + http: buildHTTPClient(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +export function buildIntegrationCleanupContext( + params: any, + rpc: RpcTransport, + pluginId: string +): IntegrationCleanupContext { + const callId = params.callId || "cleanup"; + return { + configuration: params.configuration || {}, + baseUrl: params.baseUrl || "", + organizationId: params.organizationId || "", + integration: buildIntegrationContextAccessor(rpc, callId), + http: buildHTTPClient(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +export function buildWebhookHandlerSetupContext( + params: any, + rpc: RpcTransport, + pluginId: string +): WebhookHandlerSetupContext { + const callId = params.callId || "whsetup"; + return { + webhookUrl: params.webhookUrl || "", + webhookSecret: params.webhookSecret || "", + configuration: params.configuration || {}, + integration: buildIntegrationContextAccessor(rpc, callId), + http: buildHTTPClient(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} + +export function buildWebhookHandlerCleanupContext( + params: any, + rpc: RpcTransport, + pluginId: string +): WebhookHandlerCleanupContext { + const callId = params.callId || "whcleanup"; + return { + webhookMetadata: params.webhookMetadata || {}, + configuration: params.configuration || {}, + integration: buildIntegrationContextAccessor(rpc, callId), + http: buildHTTPClient(rpc, callId), + log: createLogger(pluginId, rpc), + }; +} diff --git a/plugin-host/tsconfig.json b/plugin-host/tsconfig.json new file mode 100644 index 0000000000..b147fd942b --- /dev/null +++ b/plugin-host/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "lib": ["ES2022"], + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "paths": { + "@superplane/sdk": ["./src/sdk"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/protos/components.proto b/protos/components.proto index 3808c9c94d..daf472983b 100644 --- a/protos/components.proto +++ b/protos/components.proto @@ -84,6 +84,7 @@ message Component { string icon = 6; string color = 7; google.protobuf.Struct example_output = 8; + string source = 9; } message OutputChannel { diff --git a/protos/scripts.proto b/protos/scripts.proto new file mode 100644 index 0000000000..011a55a16a --- /dev/null +++ b/protos/scripts.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; + +package Superplane.Scripts; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; + +option go_package = "github.com/superplanehq/superplane/pkg/protos/scripts"; + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "Superplane Scripts API"; + version: "1.0"; + description: "API for Superplane in-app scripts"; + contact: { + name: "API Support"; + email: "support@superplane.com"; + }; + }; + schemes: HTTP; + schemes: HTTPS; + consumes: "application/json"; + produces: "application/json"; +}; + +service Scripts { + rpc ListScripts(ListScriptsRequest) returns (ListScriptsResponse) { + option (google.api.http) = { + get: "/api/v1/scripts" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "List scripts"; + description: "Returns a list of all scripts in the organization"; + tags: "Script"; + }; + } + + rpc DescribeScript(DescribeScriptRequest) returns (DescribeScriptResponse) { + option (google.api.http) = { + get: "/api/v1/scripts/{id}" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Describe script"; + description: "Returns a script"; + tags: "Script"; + }; + } + + rpc CreateScript(CreateScriptRequest) returns (CreateScriptResponse) { + option (google.api.http) = { + post: "/api/v1/scripts" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Create script"; + description: "Creates a new in-app script"; + tags: "Script"; + }; + } + + rpc UpdateScript(UpdateScriptRequest) returns (UpdateScriptResponse) { + option (google.api.http) = { + patch: "/api/v1/scripts/{id}" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Update script"; + description: "Updates an existing script"; + tags: "Script"; + }; + } + + rpc DeleteScript(DeleteScriptRequest) returns (DeleteScriptResponse) { + option (google.api.http) = { + delete: "/api/v1/scripts/{id}" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Delete script"; + description: "Deletes an existing script"; + tags: "Script"; + }; + } + + rpc GenerateScript(GenerateScriptRequest) returns (GenerateScriptResponse) { + option (google.api.http) = { + post: "/api/v1/scripts/{script_id}/generate" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Generate script"; + description: "Uses AI to generate or update script code based on a user prompt"; + tags: "Script"; + }; + } +} + +message ListScriptsRequest {} + +message ListScriptsResponse { + repeated Script scripts = 1; +} + +message DescribeScriptRequest { + string id = 1; +} + +message DescribeScriptResponse { + Script script = 1; +} + +message CreateScriptRequest { + Script script = 1; +} + +message CreateScriptResponse { + Script script = 1; +} + +message UpdateScriptRequest { + string id = 1; + Script script = 2; +} + +message UpdateScriptResponse { + Script script = 1; +} + +message DeleteScriptRequest { + string id = 1; +} + +message DeleteScriptResponse {} + +message GenerateScriptRequest { + string script_id = 1; + string message = 2; +} + +message GenerateScriptResponse { + string response = 1; + string source = 2; +} + +message Script { + string id = 1; + string organization_id = 2; + string name = 3; + string label = 4; + string description = 5; + string source = 6; + string manifest_json = 7; + string status = 8; + string created_by = 9; + google.protobuf.Timestamp created_at = 10; + google.protobuf.Timestamp updated_at = 11; +} diff --git a/protos/triggers.proto b/protos/triggers.proto index e6608c0d9c..a46e824fa9 100644 --- a/protos/triggers.proto +++ b/protos/triggers.proto @@ -71,4 +71,5 @@ message Trigger { string color = 5; repeated Configuration.Field configuration = 6; google.protobuf.Struct example_data = 7; + string source = 8; } diff --git a/rbac/rbac_org_policy.csv b/rbac/rbac_org_policy.csv index 5b6a3fdb21..fbc27fd676 100644 --- a/rbac/rbac_org_policy.csv +++ b/rbac/rbac_org_policy.csv @@ -33,6 +33,10 @@ p,/roles/org_admin,/org/*,blueprints,delete p,/roles/org_admin,/org/*,service_accounts,create p,/roles/org_admin,/org/*,service_accounts,update p,/roles/org_admin,/org/*,service_accounts,delete +p,/roles/org_admin,/org/*,scripts,create +p,/roles/org_admin,/org/*,scripts,read +p,/roles/org_admin,/org/*,scripts,update +p,/roles/org_admin,/org/*,scripts,delete p,/roles/org_owner,/org/*,integrations,delete p,/roles/org_owner,/org/*,org,update p,/roles/org_owner,/org/*,org,delete diff --git a/web_src/src/api-client/index.ts b/web_src/src/api-client/index.ts index cab5129b97..01516ec4ad 100644 --- a/web_src/src/api-client/index.ts +++ b/web_src/src/api-client/index.ts @@ -62,6 +62,12 @@ export { rolesDescribeRole, rolesListRoles, rolesUpdateRole, + scriptsCreateScript, + scriptsDeleteScript, + scriptsDescribeScript, + scriptsGenerateScript, + scriptsListScripts, + scriptsUpdateScript, secretsCreateSecret, secretsDeleteSecret, secretsDeleteSecretKey, @@ -534,6 +540,46 @@ export type { RolesUpdateRoleResponse, RolesUpdateRoleResponse2, RolesUpdateRoleResponses, + ScriptsCreateScriptData, + ScriptsCreateScriptError, + ScriptsCreateScriptErrors, + ScriptsCreateScriptRequest, + ScriptsCreateScriptResponse, + ScriptsCreateScriptResponse2, + ScriptsCreateScriptResponses, + ScriptsDeleteScriptData, + ScriptsDeleteScriptError, + ScriptsDeleteScriptErrors, + ScriptsDeleteScriptResponse, + ScriptsDeleteScriptResponse2, + ScriptsDeleteScriptResponses, + ScriptsDescribeScriptData, + ScriptsDescribeScriptError, + ScriptsDescribeScriptErrors, + ScriptsDescribeScriptResponse, + ScriptsDescribeScriptResponse2, + ScriptsDescribeScriptResponses, + ScriptsGenerateScriptBody, + ScriptsGenerateScriptData, + ScriptsGenerateScriptError, + ScriptsGenerateScriptErrors, + ScriptsGenerateScriptResponse, + ScriptsGenerateScriptResponse2, + ScriptsGenerateScriptResponses, + ScriptsListScriptsData, + ScriptsListScriptsError, + ScriptsListScriptsErrors, + ScriptsListScriptsResponse, + ScriptsListScriptsResponse2, + ScriptsListScriptsResponses, + ScriptsScript, + ScriptsUpdateScriptBody, + ScriptsUpdateScriptData, + ScriptsUpdateScriptError, + ScriptsUpdateScriptErrors, + ScriptsUpdateScriptResponse, + ScriptsUpdateScriptResponse2, + ScriptsUpdateScriptResponses, SecretLocal, SecretProvider, SecretsCreateSecretData, diff --git a/web_src/src/api-client/sdk.gen.ts b/web_src/src/api-client/sdk.gen.ts index 152b8da701..831f767dff 100644 --- a/web_src/src/api-client/sdk.gen.ts +++ b/web_src/src/api-client/sdk.gen.ts @@ -183,6 +183,24 @@ import type { RolesUpdateRoleData, RolesUpdateRoleErrors, RolesUpdateRoleResponses, + ScriptsCreateScriptData, + ScriptsCreateScriptErrors, + ScriptsCreateScriptResponses, + ScriptsDeleteScriptData, + ScriptsDeleteScriptErrors, + ScriptsDeleteScriptResponses, + ScriptsDescribeScriptData, + ScriptsDescribeScriptErrors, + ScriptsDescribeScriptResponses, + ScriptsGenerateScriptData, + ScriptsGenerateScriptErrors, + ScriptsGenerateScriptResponses, + ScriptsListScriptsData, + ScriptsListScriptsErrors, + ScriptsListScriptsResponses, + ScriptsUpdateScriptData, + ScriptsUpdateScriptErrors, + ScriptsUpdateScriptResponses, SecretsCreateSecretData, SecretsCreateSecretErrors, SecretsCreateSecretResponses, @@ -1178,6 +1196,96 @@ export const rolesAssignRole = ( }, }); +/** + * List scripts + * + * Returns a list of all scripts in the organization + */ +export const scriptsListScripts = ( + options?: Options, +) => + (options?.client ?? client).get({ + url: "/api/v1/scripts", + ...options, + }); + +/** + * Create script + * + * Creates a new in-app script + */ +export const scriptsCreateScript = ( + options: Options, +) => + (options.client ?? client).post({ + url: "/api/v1/scripts", + ...options, + headers: { + "Content-Type": "application/json", + ...options.headers, + }, + }); + +/** + * Delete script + * + * Deletes an existing script + */ +export const scriptsDeleteScript = ( + options: Options, +) => + (options.client ?? client).delete({ + url: "/api/v1/scripts/{id}", + ...options, + }); + +/** + * Describe script + * + * Returns a script + */ +export const scriptsDescribeScript = ( + options: Options, +) => + (options.client ?? client).get({ + url: "/api/v1/scripts/{id}", + ...options, + }); + +/** + * Update script + * + * Updates an existing script + */ +export const scriptsUpdateScript = ( + options: Options, +) => + (options.client ?? client).patch({ + url: "/api/v1/scripts/{id}", + ...options, + headers: { + "Content-Type": "application/json", + ...options.headers, + }, + }); + +/** + * Generate script + * + * Uses AI to generate or update script code based on a user prompt + */ +export const scriptsGenerateScript = ( + options: Options, +) => + (options.client ?? client).post({ + url: "/api/v1/scripts/{scriptId}/generate", + ...options, + headers: { + "Content-Type": "application/json", + ...options.headers, + }, + }); + /** * List secrets * diff --git a/web_src/src/api-client/types.gen.ts b/web_src/src/api-client/types.gen.ts index 57b7747d74..a6b790d849 100644 --- a/web_src/src/api-client/types.gen.ts +++ b/web_src/src/api-client/types.gen.ts @@ -304,6 +304,7 @@ export type ComponentsComponent = { exampleOutput?: { [key: string]: unknown; }; + source?: string; }; export type ComponentsComponentAction = { @@ -839,6 +840,57 @@ export type RolesUpdateRoleResponse = { role?: RolesRole; }; +export type ScriptsCreateScriptRequest = { + script?: ScriptsScript; +}; + +export type ScriptsCreateScriptResponse = { + script?: ScriptsScript; +}; + +export type ScriptsDeleteScriptResponse = { + [key: string]: unknown; +}; + +export type ScriptsDescribeScriptResponse = { + script?: ScriptsScript; +}; + +export type ScriptsGenerateScriptBody = { + message?: string; +}; + +export type ScriptsGenerateScriptResponse = { + response?: string; + source?: string; +}; + +export type ScriptsListScriptsResponse = { + scripts?: Array; +}; + +export type ScriptsScript = { + id?: string; + organizationId?: string; + name?: string; + label?: string; + description?: string; + source?: string; + manifestJson?: string; + status?: string; + createdBy?: string; + createdAt?: string; + updatedAt?: string; +}; + +export type ScriptsUpdateScriptBody = { + script?: ScriptsScript; +}; + +export type ScriptsUpdateScriptResponse = { + script?: ScriptsScript; +}; + /** * Local secrets are stored and managed by SuperPlane itself. */ @@ -1037,6 +1089,7 @@ export type TriggersTrigger = { exampleData?: { [key: string]: unknown; }; + source?: string; }; export type UsersAccountProvider = { @@ -2853,6 +2906,164 @@ export type RolesAssignRoleResponses = { export type RolesAssignRoleResponse2 = RolesAssignRoleResponses[keyof RolesAssignRoleResponses]; +export type ScriptsListScriptsData = { + body?: never; + path?: never; + query?: never; + url: "/api/v1/scripts"; +}; + +export type ScriptsListScriptsErrors = { + /** + * An unexpected error response. + */ + default: GooglerpcStatus; +}; + +export type ScriptsListScriptsError = ScriptsListScriptsErrors[keyof ScriptsListScriptsErrors]; + +export type ScriptsListScriptsResponses = { + /** + * A successful response. + */ + 200: ScriptsListScriptsResponse; +}; + +export type ScriptsListScriptsResponse2 = ScriptsListScriptsResponses[keyof ScriptsListScriptsResponses]; + +export type ScriptsCreateScriptData = { + body: ScriptsCreateScriptRequest; + path?: never; + query?: never; + url: "/api/v1/scripts"; +}; + +export type ScriptsCreateScriptErrors = { + /** + * An unexpected error response. + */ + default: GooglerpcStatus; +}; + +export type ScriptsCreateScriptError = ScriptsCreateScriptErrors[keyof ScriptsCreateScriptErrors]; + +export type ScriptsCreateScriptResponses = { + /** + * A successful response. + */ + 200: ScriptsCreateScriptResponse; +}; + +export type ScriptsCreateScriptResponse2 = ScriptsCreateScriptResponses[keyof ScriptsCreateScriptResponses]; + +export type ScriptsDeleteScriptData = { + body?: never; + path: { + id: string; + }; + query?: never; + url: "/api/v1/scripts/{id}"; +}; + +export type ScriptsDeleteScriptErrors = { + /** + * An unexpected error response. + */ + default: GooglerpcStatus; +}; + +export type ScriptsDeleteScriptError = ScriptsDeleteScriptErrors[keyof ScriptsDeleteScriptErrors]; + +export type ScriptsDeleteScriptResponses = { + /** + * A successful response. + */ + 200: ScriptsDeleteScriptResponse; +}; + +export type ScriptsDeleteScriptResponse2 = ScriptsDeleteScriptResponses[keyof ScriptsDeleteScriptResponses]; + +export type ScriptsDescribeScriptData = { + body?: never; + path: { + id: string; + }; + query?: never; + url: "/api/v1/scripts/{id}"; +}; + +export type ScriptsDescribeScriptErrors = { + /** + * An unexpected error response. + */ + default: GooglerpcStatus; +}; + +export type ScriptsDescribeScriptError = ScriptsDescribeScriptErrors[keyof ScriptsDescribeScriptErrors]; + +export type ScriptsDescribeScriptResponses = { + /** + * A successful response. + */ + 200: ScriptsDescribeScriptResponse; +}; + +export type ScriptsDescribeScriptResponse2 = ScriptsDescribeScriptResponses[keyof ScriptsDescribeScriptResponses]; + +export type ScriptsUpdateScriptData = { + body: ScriptsUpdateScriptBody; + path: { + id: string; + }; + query?: never; + url: "/api/v1/scripts/{id}"; +}; + +export type ScriptsUpdateScriptErrors = { + /** + * An unexpected error response. + */ + default: GooglerpcStatus; +}; + +export type ScriptsUpdateScriptError = ScriptsUpdateScriptErrors[keyof ScriptsUpdateScriptErrors]; + +export type ScriptsUpdateScriptResponses = { + /** + * A successful response. + */ + 200: ScriptsUpdateScriptResponse; +}; + +export type ScriptsUpdateScriptResponse2 = ScriptsUpdateScriptResponses[keyof ScriptsUpdateScriptResponses]; + +export type ScriptsGenerateScriptData = { + body: ScriptsGenerateScriptBody; + path: { + scriptId: string; + }; + query?: never; + url: "/api/v1/scripts/{scriptId}/generate"; +}; + +export type ScriptsGenerateScriptErrors = { + /** + * An unexpected error response. + */ + default: GooglerpcStatus; +}; + +export type ScriptsGenerateScriptError = ScriptsGenerateScriptErrors[keyof ScriptsGenerateScriptErrors]; + +export type ScriptsGenerateScriptResponses = { + /** + * A successful response. + */ + 200: ScriptsGenerateScriptResponse; +}; + +export type ScriptsGenerateScriptResponse2 = ScriptsGenerateScriptResponses[keyof ScriptsGenerateScriptResponses]; + export type SecretsListSecretsData = { body?: never; path?: never; diff --git a/web_src/src/ui/BuildingBlocksSidebar/index.tsx b/web_src/src/ui/BuildingBlocksSidebar/index.tsx index 8303404f32..e5fb6dfc9d 100644 --- a/web_src/src/ui/BuildingBlocksSidebar/index.tsx +++ b/web_src/src/ui/BuildingBlocksSidebar/index.tsx @@ -8,7 +8,7 @@ import { resolveIcon } from "@/lib/utils"; import { isCustomComponentsEnabled } from "@/lib/env"; import { getBackgroundColorClass } from "@/utils/colors"; import { getComponentSubtype } from "../buildingBlocks"; -import { ChevronRight, GripVerticalIcon, Plus, Search, StickyNote, X } from "lucide-react"; +import { ChevronRight, FileCode2, GripVerticalIcon, Plus, Search, StickyNote, X } from "lucide-react"; import { useCallback, useEffect, useRef, useState } from "react"; import { toTestId } from "../../utils/testID"; import { COMPONENT_SIDEBAR_WIDTH_STORAGE_KEY } from "../CanvasPage"; @@ -69,6 +69,7 @@ export interface BuildingBlock { isLive?: boolean; // marks items that actually work now integrationName?: string; // for components/triggers from integrations deprecated?: boolean; // marks items that are deprecated + source?: string; // "script" for custom components, "plugin" for plugin components } export type BuildingBlockCategory = { @@ -85,6 +86,7 @@ export interface BuildingBlocksSidebarProps { disabledMessage?: string; onBlockClick?: (block: BuildingBlock) => void; onAddNote?: () => void; + onOpenScripts?: () => void; } export function BuildingBlocksSidebar({ @@ -96,6 +98,7 @@ export function BuildingBlocksSidebar({ disabledMessage, onBlockClick, onAddNote, + onOpenScripts, }: BuildingBlocksSidebarProps) { const disabledTooltip = disabledMessage || "Finish configuring the selected component first"; @@ -225,6 +228,7 @@ export function BuildingBlocksSidebar({ const categoryOrder: Record = { Core: 0, + "Custom Components": 1, Bundles: 2, }; @@ -311,6 +315,19 @@ export function BuildingBlocksSidebar({ + {onOpenScripts && ( +
+ +
+ )} +
{sortedCategories.map((category) => ( | null = null; if (category.name === "Core") { CategoryIcon = resolveIcon("zap"); + } else if (category.name === "Custom Components") { + CategoryIcon = resolveIcon("file-code-2"); } else if (category.name === "Bundles") { CategoryIcon = resolveIcon("package"); } else if (integrationName === "smtp") { @@ -478,9 +497,9 @@ function CategorySection({ } const isCoreCategory = category.name === "Core"; + const isCustomCategory = category.name === "Custom Components"; const hasSearchTerm = query.length > 0; - // Expand if it's Core category (default) or if there's a search term (show results) - const shouldBeOpen = isCoreCategory || hasSearchTerm; + const shouldBeOpen = isCoreCategory || isCustomCategory || hasSearchTerm; return (
@@ -499,6 +518,11 @@ function CategorySection({ + {allBlocks.length === 0 && isCustomCategory && ( +

+ No custom components yet. Use the builder to create one. +

+ )} {allBlocks.map((block) => { const nameParts = block.name?.split(".") ?? []; const iconSlug = diff --git a/web_src/src/ui/CanvasPage/index.tsx b/web_src/src/ui/CanvasPage/index.tsx index 33efafcf50..1beeb3b85a 100644 --- a/web_src/src/ui/CanvasPage/index.tsx +++ b/web_src/src/ui/CanvasPage/index.tsx @@ -35,6 +35,7 @@ import { BuildingBlock, BuildingBlockCategory, BuildingBlocksSidebar } from "../ import { ComponentSidebar } from "../componentSidebar"; import { TabData } from "../componentSidebar/SidebarEventItem/SidebarEventItem"; import { EmitEventModal } from "../EmitEventModal"; +import { ScriptBuilderModal } from "../ScriptBuilderModal"; import { EventState, EventStateMap } from "../componentBase"; import { Block, BlockData } from "./Block"; import "./canvas-reset.css"; @@ -326,6 +327,7 @@ function CanvasPage(props: CanvasPageProps) { const readOnly = props.readOnly ?? false; const [currentTab, setCurrentTab] = useState<"latest" | "settings">("latest"); const [templateNodeId, setTemplateNodeId] = useState(null); + const [isScriptBuilderOpen, setIsScriptBuilderOpen] = useState(false); const [highlightedNodeIds, setHighlightedNodeIds] = useState>(new Set()); const canvasWrapperRef = useRef(null); @@ -821,6 +823,7 @@ function CanvasPage(props: CanvasPageProps) { disabledMessage="You don't have permission to edit this canvas." onBlockClick={handleBuildingBlockClick} onAddNote={handleAddNote} + onOpenScripts={() => setIsScriptBuilderOpen(true)} />
@@ -953,6 +956,13 @@ function CanvasPage(props: CanvasPageProps) { initialData={emitModalData.initialData} /> )} + + {/* Script Builder Modal */} + setIsScriptBuilderOpen(false)} + organizationId={props.organizationId || ""} + />
); } diff --git a/web_src/src/ui/ScriptBuilderModal/index.tsx b/web_src/src/ui/ScriptBuilderModal/index.tsx new file mode 100644 index 0000000000..8dad544080 --- /dev/null +++ b/web_src/src/ui/ScriptBuilderModal/index.tsx @@ -0,0 +1,502 @@ +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { useState, useRef, useEffect, useCallback } from "react"; +import Editor from "@monaco-editor/react"; +import { + scriptsListScripts, + scriptsDescribeScript, + scriptsCreateScript, + scriptsUpdateScript, + scriptsDeleteScript, + scriptsGenerateScript, +} from "@/api-client/sdk.gen"; +import type { ScriptsScript } from "@/api-client/types.gen"; +import { withOrganizationHeader } from "@/utils/withOrganizationHeader"; +import { Dialog, DialogContent } from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Badge } from "@/components/ui/badge"; +import { toast } from "sonner"; +import { FileCode2, Send, Save, Trash2, Bot, User, Loader2, Plus, Rocket } from "lucide-react"; + +interface ChatMessage { + role: "user" | "assistant"; + content: string; +} + +function statusVariant(status?: string): "default" | "secondary" | "destructive" | "outline" { + switch (status) { + case "active": + return "default"; + case "error": + return "destructive"; + default: + return "secondary"; + } +} + +interface ScriptBuilderModalProps { + isOpen: boolean; + onClose: () => void; + organizationId: string; +} + +export function ScriptBuilderModal({ isOpen, onClose, organizationId }: ScriptBuilderModalProps) { + const queryClient = useQueryClient(); + + const [selectedScriptId, setSelectedScriptId] = useState(null); + const [scriptName, setScriptName] = useState(""); + const [scriptLabel, setScriptLabel] = useState(""); + const [source, setSource] = useState(""); + const [chatMessages, setChatMessages] = useState([]); + const [chatInput, setChatInput] = useState(""); + const [isDirty, setIsDirty] = useState(false); + const chatEndRef = useRef(null); + + const { data: scriptsList } = useQuery({ + queryKey: ["scripts", organizationId], + queryFn: async () => { + const response = await scriptsListScripts(withOrganizationHeader({})); + return response.data?.scripts || []; + }, + enabled: isOpen && !!organizationId, + }); + + const { data: script } = useQuery({ + queryKey: ["script", selectedScriptId], + queryFn: async () => { + const response = await scriptsDescribeScript(withOrganizationHeader({ path: { id: selectedScriptId! } })); + return response.data?.script; + }, + enabled: !!selectedScriptId, + }); + + useEffect(() => { + if (script) { + setScriptName(script.name || ""); + setScriptLabel(script.label || ""); + setSource(script.source || ""); + setIsDirty(false); + setChatMessages([]); + } + }, [script]); + + useEffect(() => { + chatEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [chatMessages]); + + useEffect(() => { + if (!isOpen) { + setSelectedScriptId(null); + setScriptName(""); + setScriptLabel(""); + setSource(""); + setChatMessages([]); + setChatInput(""); + setIsDirty(false); + } + }, [isOpen]); + + const createMutation = useMutation({ + mutationFn: async () => { + const name = `script-${Date.now()}`; + const response = await scriptsCreateScript( + withOrganizationHeader({ + body: { + script: { + name, + label: "New Component", + description: "", + }, + }, + }), + ); + return response.data?.script; + }, + onSuccess: (newScript) => { + queryClient.invalidateQueries({ queryKey: ["scripts", organizationId] }); + if (newScript?.id) { + setSelectedScriptId(newScript.id); + } + }, + onError: (error) => { + toast.error(`Failed to create component: ${error.message}`); + }, + }); + + const updateMutation = useMutation({ + mutationFn: async () => { + await scriptsUpdateScript( + withOrganizationHeader({ + path: { id: selectedScriptId! }, + body: { + script: { + name: scriptName, + label: scriptLabel, + source, + }, + }, + }), + ); + }, + onSuccess: () => { + setIsDirty(false); + queryClient.invalidateQueries({ queryKey: ["script", selectedScriptId] }); + queryClient.invalidateQueries({ queryKey: ["scripts", organizationId] }); + toast.success("Component saved"); + }, + onError: () => { + toast.error("Failed to save component"); + }, + }); + + const deployMutation = useMutation({ + mutationFn: async () => { + await scriptsUpdateScript( + withOrganizationHeader({ + path: { id: selectedScriptId! }, + body: { + script: { + name: scriptName, + label: scriptLabel, + source, + status: "active", + }, + }, + }), + ); + }, + onSuccess: () => { + setIsDirty(false); + queryClient.invalidateQueries({ queryKey: ["scripts", organizationId] }); + queryClient.invalidateQueries({ queryKey: ["components"] }); + queryClient.invalidateQueries({ queryKey: ["triggers"] }); + toast.success("Component deployed"); + onClose(); + }, + onError: (error) => { + toast.error(`Failed to deploy component: ${error.message}`); + }, + }); + + const deactivateMutation = useMutation({ + mutationFn: async () => { + await scriptsUpdateScript( + withOrganizationHeader({ + path: { id: selectedScriptId! }, + body: { + script: { + status: "draft", + }, + }, + }), + ); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["script", selectedScriptId] }); + queryClient.invalidateQueries({ queryKey: ["scripts", organizationId] }); + toast.success("Component deactivated"); + }, + onError: (error) => { + toast.error(`Failed to deactivate: ${error.message}`); + }, + }); + + const deleteMutation = useMutation({ + mutationFn: async () => { + await scriptsDeleteScript(withOrganizationHeader({ path: { id: selectedScriptId! } })); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["scripts", organizationId] }); + setSelectedScriptId(null); + setScriptName(""); + setScriptLabel(""); + setSource(""); + setChatMessages([]); + toast.success("Component deleted"); + }, + }); + + const generateMutation = useMutation({ + mutationFn: async (message: string) => { + const response = await scriptsGenerateScript( + withOrganizationHeader({ + path: { scriptId: selectedScriptId! }, + body: { message }, + }), + ); + return response.data; + }, + onSuccess: (data) => { + if (data?.response) { + setChatMessages((prev) => [...prev, { role: "assistant", content: data.response! }]); + } + if (data?.source) { + setSource(data.source!); + setIsDirty(true); + } + }, + onError: () => { + setChatMessages((prev) => [ + ...prev, + { role: "assistant", content: "Sorry, AI generation failed. Please try again." }, + ]); + }, + }); + + const handleSendChat = useCallback(() => { + const message = chatInput.trim(); + if (!message || generateMutation.isPending) return; + + setChatMessages((prev) => [...prev, { role: "user", content: message }]); + setChatInput(""); + generateMutation.mutate(message); + }, [chatInput, generateMutation]); + + const handleSourceChange = useCallback((value: string | undefined) => { + setSource(value || ""); + setIsDirty(true); + }, []); + + const scripts = scriptsList || []; + + return ( + !open && onClose()}> + +
+ {/* Left sidebar - Script list */} +
+
+

Custom Components

+ +
+
+ {scripts.length === 0 && ( +
+ +

No custom components yet

+
+ )} + {scripts.map((s: ScriptsScript) => ( + + ))} +
+
+ + {selectedScriptId ? ( + <> + {/* Center panel - AI Chat */} +
+
+

AI Assistant

+

Describe what you want the component to do

+
+ +
+ {chatMessages.length === 0 && ( +
+ +

+ Describe what you need and the AI will generate TypeScript code using the @superplane/sdk API. +

+
+ )} + {chatMessages.map((msg, i) => ( +
+
+ {msg.role === "user" ? ( + + ) : ( + + )} +
+
+
+                          {msg.content}
+                        
+
+
+ ))} + {generateMutation.isPending && ( +
+
+ +
+
Generating...
+
+ )} +
+
+ +
+
+ setChatInput(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSendChat(); + } + }} + placeholder="Describe what you need..." + className="flex-1" + /> + +
+
+
+ + {/* Right panel - Code Editor */} +
+
+
+ { + setScriptLabel(e.target.value); + setIsDirty(true); + }} + placeholder="Component label" + className="flex-1 text-sm" + /> + {script?.status || "draft"} +
+
+ { + setScriptName(e.target.value); + setIsDirty(true); + }} + placeholder="component-name (used as identifier)" + className="flex-1 text-xs font-mono" + /> +
+
+ +
+ +
+ +
+ +
+ {script?.status === "active" && ( + + )} + + +
+
+
+ + ) : ( +
+
+ +

+ {scripts.length === 0 + ? "Create your first custom component." + : "Select a component from the sidebar to edit it."} +

+ +
+
+ )} +
+ +
+ ); +} diff --git a/web_src/src/ui/buildingBlocks.ts b/web_src/src/ui/buildingBlocks.ts index b0d1f400e9..d37913247b 100644 --- a/web_src/src/ui/buildingBlocks.ts +++ b/web_src/src/ui/buildingBlocks.ts @@ -42,38 +42,49 @@ export function buildBuildingBlockCategories( const filteredTriggers = triggers.filter((trigger) => !deprecatedTriggerNames.has(trigger.name ?? "")); const filteredComponents = components.filter((component) => !deprecatedComponentNames.has(component.name ?? "")); - // Combine triggers and components into a single "Core" category - const coreBlocks: BuildingBlock[] = [ - ...filteredTriggers.map((t): BuildingBlock => { - const block: BuildingBlock = { - name: t.name!, - label: t.label, - description: t.description, - type: "trigger", - configuration: t.configuration, - icon: t.icon, - color: t.color, - isLive: true, - }; - block.componentSubtype = getComponentSubtype(block); - return block; - }), - ...filteredComponents.map((c): BuildingBlock => { - const block: BuildingBlock = { - name: c.name!, - label: c.label, - description: c.description, - type: "component", - outputChannels: c.outputChannels, - configuration: c.configuration, - icon: c.icon, - color: c.color, - isLive: true, - }; - block.componentSubtype = getComponentSubtype(block); - return block; - }), - ]; + const coreBlocks: BuildingBlock[] = []; + const customBlocks: BuildingBlock[] = []; + + filteredTriggers.forEach((t) => { + const block: BuildingBlock = { + name: t.name!, + label: t.label, + description: t.description, + type: "trigger", + configuration: t.configuration, + icon: t.icon, + color: t.color, + isLive: true, + source: t.source, + }; + block.componentSubtype = getComponentSubtype(block); + if (t.source === "script") { + customBlocks.push(block); + } else { + coreBlocks.push(block); + } + }); + + filteredComponents.forEach((c) => { + const block: BuildingBlock = { + name: c.name!, + label: c.label, + description: c.description, + type: "component", + outputChannels: c.outputChannels, + configuration: c.configuration, + icon: c.icon, + color: c.color, + isLive: true, + source: c.source, + }; + block.componentSubtype = getComponentSubtype(block); + if (c.source === "script") { + customBlocks.push(block); + } else { + coreBlocks.push(block); + } + }); const liveCategories: BuildingBlockCategory[] = [ { @@ -100,6 +111,11 @@ export function buildBuildingBlockCategories( }, ]; + liveCategories.push({ + name: "Custom Components", + blocks: customBlocks, + }); + // Add a category for each available application with its components and triggers availableIntegrations.forEach((integration) => { const blocks: BuildingBlock[] = [];