From bbe513e0c50a676d741141f1e0cdb52dad6a479f Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Mon, 16 Mar 2026 15:34:43 -0500 Subject: [PATCH] feat(api-docs): add externalDocs to tags, strip absolute URLs, fix link pipeline - Add standard OpenAPI `externalDocs` field to all tags.yml files that have `x-related` entries (uses first link as the primary doc link) - Convert `externalDocs` to `{title, href}` objects in related links instead of bare URL strings - Strip `https://docs.influxdata.com` from description/summary fields in `transformDocLinks()` so Hugo pages use relative paths - Fix article generation reading from absolutified download spec instead of the Hugo spec with relative links (new `hugoSpecPath` output) - Add `externalDocs.url` support to `absolutifyLinks()` for downloads --- api-docs/enterprise_influxdb/v1/tags.yml | 43 +- api-docs/influxdb/cloud/tags.yml | 248 ++- api-docs/influxdb/v1/tags.yml | 41 +- api-docs/influxdb/v2/tags.yml | 293 ++-- .../cloud-dedicated/management/tags.yml | 35 +- api-docs/influxdb3/cloud-dedicated/tags.yml | 61 +- api-docs/influxdb3/cloud-serverless/tags.yml | 334 ++-- .../influxdb3/clustered/management/tags.yml | 35 +- api-docs/influxdb3/clustered/tags.yml | 60 +- api-docs/influxdb3/core/tags.yml | 52 +- api-docs/influxdb3/enterprise/tags.yml | 47 +- .../scripts/dist/generate-openapi-articles.js | 1355 ++++++++++------- .../dist/openapi-paths-to-hugo-data/index.js | 12 +- api-docs/scripts/generate-openapi-articles.ts | 42 +- .../openapi-paths-to-hugo-data/index.ts | 12 +- 15 files changed, 1393 insertions(+), 1277 deletions(-) diff --git a/api-docs/enterprise_influxdb/v1/tags.yml b/api-docs/enterprise_influxdb/v1/tags.yml index 185d9a3a8..aba8cca01 100644 --- a/api-docs/enterprise_influxdb/v1/tags.yml +++ b/api-docs/enterprise_influxdb/v1/tags.yml @@ -1,40 +1,24 @@ tags: System Information: - description: > - Check server status, health, and version information for an InfluxDB - Enterprise v1 instance. - + description: | + Check server status, health, and version information for an InfluxDB Enterprise v1 instance. Query: - description: > - Query data using InfluxQL via the `/query` endpoint, supporting both read - queries (SELECT, SHOW) and management queries (CREATE, DROP, ALTER). - + description: | + Query data using InfluxQL via the `/query` endpoint, supporting both read queries (SELECT, SHOW) and management queries (CREATE, DROP, ALTER). Write: - description: > - Write time series data to InfluxDB Enterprise v1 in line protocol format - using the `/write` endpoint. - + description: | + Write time series data to InfluxDB Enterprise v1 in line protocol format using the `/write` endpoint. ## Enterprise cluster parameters - - **Write Consistency**: Control write consistency across cluster nodes - Debug: - description: > - Access debugging and profiling endpoints for troubleshooting and - performance analysis of an InfluxDB Enterprise v1 instance. - + description: | + Access debugging and profiling endpoints for troubleshooting and performance analysis of an InfluxDB Enterprise v1 instance. Buckets (v2 compatible): - description: > - Manage databases as buckets using InfluxDB v2-compatible endpoints. - Provides forward compatibility with InfluxDB 2.x client libraries - and InfluxDB Enterprise 1.8+. - + description: | + Manage databases as buckets using InfluxDB v2-compatible endpoints. Provides forward compatibility with InfluxDB 2.x client libraries and InfluxDB Enterprise 1.8+. Delete (v2 compatible): - description: > - Delete data using InfluxDB v2-compatible predicate expressions. - Provides forward compatibility with InfluxDB 2.x client libraries - and InfluxDB Enterprise 1.8+. - + description: | + Delete data using InfluxDB v2-compatible predicate expressions. Provides forward compatibility with InfluxDB 2.x client libraries and InfluxDB Enterprise 1.8+. Authentication: x-traitTag: true description: | @@ -49,6 +33,9 @@ tags: - [Query string authentication](#section/Authentication/QueryAuth) - [Token authentication](#section/Authentication/TokenAuth) + externalDocs: + description: Configure authentication + url: /enterprise_influxdb/v1/administration/configure/security/authentication/ x-related: - title: Configure authentication href: /enterprise_influxdb/v1/administration/configure/security/authentication/ diff --git a/api-docs/influxdb/cloud/tags.yml b/api-docs/influxdb/cloud/tags.yml index 13decd4ea..d7936ffa4 100644 --- a/api-docs/influxdb/cloud/tags.yml +++ b/api-docs/influxdb/cloud/tags.yml @@ -8,183 +8,140 @@ tags: - [Basic authentication](#section/Authentication/BasicAuthentication) - [Querystring authentication](#section/Authentication/QuerystringAuthentication) - Authorizations (API tokens): - description: > - Create and manage API token authorizations that grant read and write - permissions to InfluxDB Cloud organization resources. + description: | + Create and manage API token authorizations that grant read and write permissions to InfluxDB Cloud organization resources. + externalDocs: + description: Manage API tokens + url: /influxdb/cloud/security/tokens/ x-related: - title: Manage API tokens href: /influxdb/cloud/security/tokens/ - Bucket Schemas: - description: > - Manage explicit schemas for InfluxDB Cloud buckets to enforce column - names and data types for measurement data. - + description: | + Manage explicit schemas for InfluxDB Cloud buckets to enforce column names and data types for measurement data. Buckets: - description: > - Create and manage named storage locations (buckets) in InfluxDB Cloud, - each with a configurable retention period. + description: | + Create and manage named storage locations (buckets) in InfluxDB Cloud, each with a configurable retention period. + externalDocs: + description: Manage buckets + url: /influxdb/cloud/organizations/buckets/ x-related: - title: Manage buckets href: /influxdb/cloud/organizations/buckets/ - Cells: - description: > + description: | Manage cells within InfluxDB Cloud dashboards. - Checks: - description: > - Create and manage monitoring checks that query data on a schedule and - generate notification statuses in InfluxDB Cloud. - + description: | + Create and manage monitoring checks that query data on a schedule and generate notification statuses in InfluxDB Cloud. Common parameters: x-traitTag: true - description: > - Common query parameters used by InfluxDB Cloud API endpoints, including - `bucket`, `bucketID`, `org`, and `orgID`. - + description: | + Common query parameters used by InfluxDB Cloud API endpoints, including `bucket`, `bucketID`, `org`, and `orgID`. Config: - description: > + description: | Retrieve configuration information for an InfluxDB Cloud instance. - Dashboards: - description: > + description: | Create and manage dashboards in InfluxDB Cloud. - DBRPs: - description: > - Manage database and retention policy (DBRP) mappings that route InfluxDB - v1-compatible requests to InfluxDB Cloud buckets. + description: | + Manage database and retention policy (DBRP) mappings that route InfluxDB v1-compatible requests to InfluxDB Cloud buckets. + externalDocs: + description: Database and retention policy mapping + url: /influxdb/cloud/reference/api/influxdb-1x/dbrp/ x-related: - title: Database and retention policy mapping href: /influxdb/cloud/reference/api/influxdb-1x/dbrp/ - Delete: - description: > - Delete time series data from an InfluxDB Cloud bucket by specifying a - time range and optional tag predicate. - + description: | + Delete time series data from an InfluxDB Cloud bucket by specifying a time range and optional tag predicate. Headers: x-traitTag: true - description: > - Standard HTTP request headers used by InfluxDB Cloud API endpoints, - including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. - + description: | + Standard HTTP request headers used by InfluxDB Cloud API endpoints, including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. Invokable Scripts: - description: > - Store, manage, and execute custom Flux scripts in InfluxDB Cloud. - Scripts accept runtime parameters and can be invoked via dedicated - endpoints. - + description: | + Store, manage, and execute custom Flux scripts in InfluxDB Cloud. Scripts accept runtime parameters and can be invoked via dedicated endpoints. Labels: - description: > - Create and manage labels for organizing InfluxDB Cloud resources such as - dashboards, tasks, and buckets. - + description: | + Create and manage labels for organizing InfluxDB Cloud resources such as dashboards, tasks, and buckets. Legacy Authorizations: - description: > + description: | Manage legacy (v1-compatible) authorization credentials in InfluxDB Cloud. - Legacy Query: - description: > - Query data using InfluxQL via the v1-compatible `/query` endpoint in - InfluxDB Cloud. - + description: | + Query data using InfluxQL via the v1-compatible `/query` endpoint in InfluxDB Cloud. Legacy Write: - description: > + description: | Write data using the v1-compatible `/write` endpoint in InfluxDB Cloud. - Limits: - description: > + description: | Retrieve rate limits and usage quotas for an InfluxDB Cloud organization. - NotificationEndpoints: - description: > - Create and manage notification endpoints that receive alert notifications - from InfluxDB Cloud monitoring checks. - + description: | + Create and manage notification endpoints that receive alert notifications from InfluxDB Cloud monitoring checks. NotificationRules: - description: > - Create and manage notification rules that define when and how InfluxDB - Cloud sends notifications to configured endpoints. - + description: | + Create and manage notification rules that define when and how InfluxDB Cloud sends notifications to configured endpoints. Organizations: - description: > - View and manage InfluxDB Cloud organizations, which are workspaces that - group users, buckets, and resources. + description: | + View and manage InfluxDB Cloud organizations, which are workspaces that group users, buckets, and resources. + externalDocs: + description: View and manage organizations + url: /influxdb/cloud/organizations/ x-related: - title: View and manage organizations href: /influxdb/cloud/organizations/ - Pagination: x-traitTag: true - description: > - Query parameters for paginating results from list operations in the - InfluxDB Cloud API. - + description: | + Query parameters for paginating results from list operations in the InfluxDB Cloud API. Ping: - description: > + description: | Check the availability of the InfluxDB Cloud instance. - Query data: - description: > - Retrieve data, analyze queries, and get query suggestions using the - InfluxDB Cloud query API. + description: | + Retrieve data, analyze queries, and get query suggestions using the InfluxDB Cloud query API. + externalDocs: + description: Query data + url: /influxdb/cloud/query-data/ x-related: - title: Query data href: /influxdb/cloud/query-data/ - Quick start: x-traitTag: true - description: > - Get started authenticating, writing, and querying data with the InfluxDB - Cloud API. - + description: | + Get started authenticating, writing, and querying data with the InfluxDB Cloud API. Resources: - description: > - Retrieve a list of top-level resource types available in the InfluxDB - Cloud API. - + description: | + Retrieve a list of top-level resource types available in the InfluxDB Cloud API. Response codes: x-traitTag: true - description: > - Standard HTTP status codes returned by InfluxDB Cloud API endpoints and - their meanings. - + description: | + Standard HTTP status codes returned by InfluxDB Cloud API endpoints and their meanings. Routes: - description: > + description: | Retrieve top-level routes for the InfluxDB Cloud API. - Rules: - description: > + description: | Manage notification rules in InfluxDB Cloud. - Secrets: - description: > - Create and manage secrets (key-value pairs) for use in InfluxDB Cloud - Flux scripts and tasks. - + description: | + Create and manage secrets (key-value pairs) for use in InfluxDB Cloud Flux scripts and tasks. Security and access endpoints: - description: > - Endpoints for managing authentication and access control in InfluxDB - Cloud. - + description: | + Endpoints for managing authentication and access control in InfluxDB Cloud. Setup: - description: > - Configure an initial InfluxDB Cloud instance, including creating the - initial user, organization, and bucket. - + description: | + Configure an initial InfluxDB Cloud instance, including creating the initial user, organization, and bucket. Signin: - description: > - Create a user session by signing in with username and password - credentials. - + description: | + Create a user session by signing in with username and password credentials. Signout: - description: > + description: | End a user session by signing out. - Supported operations: x-traitTag: true description: | @@ -197,62 +154,57 @@ tags: | **Read** | `GET` | Retrieve a resource or list resources. | | **Update** | `PUT`, `PATCH` | Replace or modify an existing resource. | | **Delete** | `DELETE` | Remove a resource. | - System information endpoints: - description: > - Endpoints for retrieving system-level information about the InfluxDB - Cloud instance. - + description: | + Endpoints for retrieving system-level information about the InfluxDB Cloud instance. Tasks: - description: > - Schedule and manage Flux tasks that process and transform data on a - recurring basis in InfluxDB Cloud. + description: | + Schedule and manage Flux tasks that process and transform data on a recurring basis in InfluxDB Cloud. + externalDocs: + description: Get started with tasks + url: /influxdb/cloud/process-data/get-started/ x-related: - title: Get started with tasks href: /influxdb/cloud/process-data/get-started/ - Telegraf Plugins: - description: > - Retrieve available Telegraf plugin configuration templates for use with - InfluxDB Cloud. - + description: | + Retrieve available Telegraf plugin configuration templates for use with InfluxDB Cloud. Telegrafs: - description: > - Create and manage Telegraf agent configurations that collect and write - data to InfluxDB Cloud. - + description: | + Create and manage Telegraf agent configurations that collect and write data to InfluxDB Cloud. Templates: - description: > - Export and apply InfluxDB templates, and manage template stacks for - InfluxDB Cloud. + description: | + Export and apply InfluxDB templates, and manage template stacks for InfluxDB Cloud. + externalDocs: + description: InfluxDB templates + url: /influxdb/cloud/influxdb-templates/ x-related: - title: InfluxDB templates href: /influxdb/cloud/influxdb-templates/ - Usage: - description: > - Retrieve usage metrics and cardinality data for an InfluxDB Cloud - organization. - + description: | + Retrieve usage metrics and cardinality data for an InfluxDB Cloud organization. Users: - description: > + description: | View specific users that are members of your InfluxDB Cloud organization. + externalDocs: + description: Manage users + url: /influxdb/cloud/organizations/users/ x-related: - title: Manage users href: /influxdb/cloud/organizations/users/ - Variables: - description: > + description: | Create and manage variables for use in InfluxDB Cloud dashboards. - Views: - description: > + description: | Manage cell views within InfluxDB Cloud dashboards. - Write data: - description: > - Write time series data to InfluxDB Cloud buckets in line protocol format - using the `/api/v2/write` endpoint. + description: | + Write time series data to InfluxDB Cloud buckets in line protocol format using the `/api/v2/write` endpoint. + externalDocs: + description: Write data + url: /influxdb/cloud/write-data/ x-related: - title: Write data href: /influxdb/cloud/write-data/ diff --git a/api-docs/influxdb/v1/tags.yml b/api-docs/influxdb/v1/tags.yml index 320746156..9844030ab 100644 --- a/api-docs/influxdb/v1/tags.yml +++ b/api-docs/influxdb/v1/tags.yml @@ -1,36 +1,22 @@ tags: System Information: - description: > - Check server status, health, and version information for an InfluxDB - v1 instance. - + description: | + Check server status, health, and version information for an InfluxDB v1 instance. Query: - description: > - Query data using InfluxQL via the `/query` endpoint, supporting both read - queries (SELECT, SHOW) and management queries (CREATE, DROP, ALTER). - + description: | + Query data using InfluxQL via the `/query` endpoint, supporting both read queries (SELECT, SHOW) and management queries (CREATE, DROP, ALTER). Write: - description: > - Write time series data to InfluxDB v1 in line protocol format using the - `/write` endpoint. - + description: | + Write time series data to InfluxDB v1 in line protocol format using the `/write` endpoint. Debug: - description: > - Access debugging and profiling endpoints for troubleshooting and - performance analysis of an InfluxDB v1 instance. - + description: | + Access debugging and profiling endpoints for troubleshooting and performance analysis of an InfluxDB v1 instance. Buckets (v2 compatible): - description: > - Manage databases as buckets using InfluxDB v2-compatible endpoints. - Provides forward compatibility with InfluxDB 2.x client libraries - and InfluxDB 1.8+. - + description: | + Manage databases as buckets using InfluxDB v2-compatible endpoints. Provides forward compatibility with InfluxDB 2.x client libraries and InfluxDB 1.8+. Delete (v2 compatible): - description: > - Delete data using InfluxDB v2-compatible predicate expressions. - Provides forward compatibility with InfluxDB 2.x client libraries - and InfluxDB 1.8+. - + description: | + Delete data using InfluxDB v2-compatible predicate expressions. Provides forward compatibility with InfluxDB 2.x client libraries and InfluxDB 1.8+. Authentication: x-traitTag: true description: | @@ -45,6 +31,9 @@ tags: - [Query string authentication](#section/Authentication/QueryAuth) - [Token authentication](#section/Authentication/TokenAuth) + externalDocs: + description: Manage authentication and authorization + url: /influxdb/v1/administration/authentication_and_authorization/ x-related: - title: Manage authentication and authorization href: /influxdb/v1/administration/authentication_and_authorization/ diff --git a/api-docs/influxdb/v2/tags.yml b/api-docs/influxdb/v2/tags.yml index b82671d3f..f6d265ebb 100644 --- a/api-docs/influxdb/v2/tags.yml +++ b/api-docs/influxdb/v2/tags.yml @@ -8,221 +8,168 @@ tags: - [Basic authentication](#section/Authentication/BasicAuthentication) - [Querystring authentication](#section/Authentication/QuerystringAuthentication) - Authorizations (API tokens): - description: > - Create and manage API token authorizations that grant read and write - permissions to InfluxDB OSS v2 organization resources. + description: | + Create and manage API token authorizations that grant read and write permissions to InfluxDB OSS v2 organization resources. + externalDocs: + description: Manage API tokens + url: /influxdb/v2/security/tokens/ x-related: - title: Manage API tokens href: /influxdb/v2/security/tokens/ - Authorizations (v1-compatible): - description: > + description: | Manage v1-compatible legacy authorization credentials in InfluxDB OSS v2. - Backup: - description: > - Back up InfluxDB OSS v2 data, including time series data and metadata, - for use in restore operations. - + description: | + Back up InfluxDB OSS v2 data, including time series data and metadata, for use in restore operations. Buckets: - description: > - Create and manage named storage locations (buckets) in InfluxDB OSS v2, - each with a configurable retention period. + description: | + Create and manage named storage locations (buckets) in InfluxDB OSS v2, each with a configurable retention period. + externalDocs: + description: Manage buckets + url: /influxdb/v2/organizations/buckets/ x-related: - title: Manage buckets href: /influxdb/v2/organizations/buckets/ - Cells: - description: > + description: | Manage cells within InfluxDB OSS v2 dashboards. - Checks: - description: > - Create and manage monitoring checks that query data on a schedule and - generate notification statuses in InfluxDB OSS v2. - + description: | + Create and manage monitoring checks that query data on a schedule and generate notification statuses in InfluxDB OSS v2. Common parameters: x-traitTag: true - description: > - Common query parameters used by InfluxDB OSS v2 API endpoints, including - `bucket`, `bucketID`, `org`, and `orgID`. - + description: | + Common query parameters used by InfluxDB OSS v2 API endpoints, including `bucket`, `bucketID`, `org`, and `orgID`. Compatibility endpoints: x-traitTag: true - description: > - InfluxDB v1-compatible API endpoints for backward compatibility with - InfluxDB 1.x clients, tools, and integrations such as Grafana and - Telegraf. - + description: | + InfluxDB v1-compatible API endpoints for backward compatibility with InfluxDB 1.x clients, tools, and integrations such as Grafana and Telegraf. Config: - description: > + description: | Retrieve configuration information for an InfluxDB OSS v2 instance. - Dashboards: - description: > + description: | Create and manage dashboards in InfluxDB OSS v2. - DBRPs: - description: > - Manage database and retention policy (DBRP) mappings that route InfluxDB - v1-compatible requests to InfluxDB OSS v2 buckets. + description: | + Manage database and retention policy (DBRP) mappings that route InfluxDB v1-compatible requests to InfluxDB OSS v2 buckets. + externalDocs: + description: Database and retention policy mapping + url: /influxdb/v2/reference/api/influxdb-1x/dbrp/ x-related: - title: Database and retention policy mapping href: /influxdb/v2/reference/api/influxdb-1x/dbrp/ - Debug: - description: > - Generate Go runtime profiling and trace reports for troubleshooting and - performance analysis of an InfluxDB OSS v2 instance. - + description: | + Generate Go runtime profiling and trace reports for troubleshooting and performance analysis of an InfluxDB OSS v2 instance. Delete: - description: > - Delete time series data from an InfluxDB OSS v2 bucket by specifying a - time range and optional tag predicate. - + description: | + Delete time series data from an InfluxDB OSS v2 bucket by specifying a time range and optional tag predicate. Headers: x-traitTag: true - description: > - Standard HTTP request headers used by InfluxDB OSS v2 API endpoints, - including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. - + description: | + Standard HTTP request headers used by InfluxDB OSS v2 API endpoints, including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. Health: - description: > + description: | Check the health and readiness of an InfluxDB OSS v2 instance. - Labels: - description: > - Create and manage labels for organizing InfluxDB OSS v2 resources such as - dashboards, tasks, and buckets. - + description: | + Create and manage labels for organizing InfluxDB OSS v2 resources such as dashboards, tasks, and buckets. Metrics: - description: > - Retrieve internal metrics for an InfluxDB OSS v2 instance in Prometheus - exposition format. - + description: | + Retrieve internal metrics for an InfluxDB OSS v2 instance in Prometheus exposition format. NotificationEndpoints: - description: > - Create and manage notification endpoints that receive alert notifications - from InfluxDB OSS v2 monitoring checks. - + description: | + Create and manage notification endpoints that receive alert notifications from InfluxDB OSS v2 monitoring checks. NotificationRules: - description: > - Create and manage notification rules that define when and how InfluxDB - OSS v2 sends notifications to configured endpoints. - + description: | + Create and manage notification rules that define when and how InfluxDB OSS v2 sends notifications to configured endpoints. Organizations: - description: > - Create and manage InfluxDB OSS v2 organizations, which are workspaces - that group users, buckets, and resources. + description: | + Create and manage InfluxDB OSS v2 organizations, which are workspaces that group users, buckets, and resources. + externalDocs: + description: Manage organizations + url: /influxdb/v2/organizations/ x-related: - title: Manage organizations href: /influxdb/v2/organizations/ - Pagination: x-traitTag: true - description: > - Query parameters for paginating results from list operations in the - InfluxDB OSS v2 API. - + description: | + Query parameters for paginating results from list operations in the InfluxDB OSS v2 API. Ping: - description: > + description: | Check the availability of an InfluxDB OSS v2 instance. - Query data: - description: > - Retrieve data, analyze queries, and get query suggestions using the - InfluxDB OSS v2 query API. + description: | + Retrieve data, analyze queries, and get query suggestions using the InfluxDB OSS v2 query API. + externalDocs: + description: Query data + url: /influxdb/v2/query-data/ x-related: - title: Query data href: /influxdb/v2/query-data/ - Query data (v1-compatible): - description: > - Query data in InfluxDB OSS v2 using InfluxQL via the v1-compatible - `/query` endpoint. - + description: | + Query data in InfluxDB OSS v2 using InfluxQL via the v1-compatible `/query` endpoint. Quick start: x-traitTag: true - description: > - Get started authenticating, writing, and querying data with the InfluxDB - OSS v2 API. - + description: | + Get started authenticating, writing, and querying data with the InfluxDB OSS v2 API. Ready: - description: > + description: | Check whether an InfluxDB OSS v2 instance is ready to accept requests. - RemoteConnections: - description: > - Create and manage remote InfluxDB connections for replicating data from - an InfluxDB OSS v2 instance to a remote InfluxDB instance. - + description: | + Create and manage remote InfluxDB connections for replicating data from an InfluxDB OSS v2 instance to a remote InfluxDB instance. Replications: - description: > - Create and manage replication streams that copy data from an InfluxDB - OSS v2 bucket to a remote InfluxDB instance. - + description: | + Create and manage replication streams that copy data from an InfluxDB OSS v2 bucket to a remote InfluxDB instance. Resources: - description: > - Retrieve a list of top-level resource types available in the InfluxDB - OSS v2 API. - + description: | + Retrieve a list of top-level resource types available in the InfluxDB OSS v2 API. Response codes: x-traitTag: true - description: > - Standard HTTP status codes returned by InfluxDB OSS v2 API endpoints and - their meanings. - + description: | + Standard HTTP status codes returned by InfluxDB OSS v2 API endpoints and their meanings. Restore: - description: > - Restore InfluxDB OSS v2 data from a backup, including time series data - and metadata. - + description: | + Restore InfluxDB OSS v2 data from a backup, including time series data and metadata. Routes: - description: > + description: | Retrieve top-level routes for the InfluxDB OSS v2 API. - Rules: - description: > + description: | Manage notification rules in InfluxDB OSS v2. - Scraper Targets: - description: > - Create and manage Prometheus scraper targets that collect metrics and - write them to InfluxDB OSS v2 buckets. - + description: | + Create and manage Prometheus scraper targets that collect metrics and write them to InfluxDB OSS v2 buckets. Secrets: - description: > - Create and manage secrets (key-value pairs) for use in InfluxDB OSS v2 - Flux scripts and tasks. - + description: | + Create and manage secrets (key-value pairs) for use in InfluxDB OSS v2 Flux scripts and tasks. Security and access endpoints: - description: > - Endpoints for managing authentication and access control in InfluxDB - OSS v2. - + description: | + Endpoints for managing authentication and access control in InfluxDB OSS v2. Setup: - description: > - Configure a new InfluxDB OSS v2 instance, including creating the initial - user, organization, bucket, and API token. + description: | + Configure a new InfluxDB OSS v2 instance, including creating the initial user, organization, bucket, and API token. + externalDocs: + description: Set up InfluxDB + url: /influxdb/v2/get-started/ x-related: - title: Set up InfluxDB href: /influxdb/v2/get-started/ - Signin: - description: > - Create a user session by signing in with username and password - credentials. - + description: | + Create a user session by signing in with username and password credentials. Signout: - description: > + description: | End a user session by signing out. - Sources: - description: > + description: | Manage data sources configured in InfluxDB OSS v2. - Supported operations: x-traitTag: true description: | @@ -235,63 +182,57 @@ tags: | **Read** | `GET` | Retrieve a resource or list resources. | | **Update** | `PUT`, `PATCH` | Replace or modify an existing resource. | | **Delete** | `DELETE` | Remove a resource. | - System information endpoints: - description: > - Endpoints for retrieving system-level information about the InfluxDB - OSS v2 instance. - + description: | + Endpoints for retrieving system-level information about the InfluxDB OSS v2 instance. Tasks: - description: > - Schedule and manage Flux tasks that process and transform data on a - recurring basis in InfluxDB OSS v2. + description: | + Schedule and manage Flux tasks that process and transform data on a recurring basis in InfluxDB OSS v2. + externalDocs: + description: Get started with tasks + url: /influxdb/v2/process-data/get-started/ x-related: - title: Get started with tasks href: /influxdb/v2/process-data/get-started/ - Telegraf Plugins: - description: > - Retrieve available Telegraf plugin configuration templates for use with - InfluxDB OSS v2. - + description: | + Retrieve available Telegraf plugin configuration templates for use with InfluxDB OSS v2. Telegrafs: - description: > - Create and manage Telegraf agent configurations that collect and write - data to InfluxDB OSS v2. - + description: | + Create and manage Telegraf agent configurations that collect and write data to InfluxDB OSS v2. Templates: - description: > - Export and apply InfluxDB templates, and manage template stacks for - InfluxDB OSS v2. + description: | + Export and apply InfluxDB templates, and manage template stacks for InfluxDB OSS v2. + externalDocs: + description: InfluxDB templates + url: /influxdb/v2/influxdb-templates/ x-related: - title: InfluxDB templates href: /influxdb/v2/influxdb-templates/ - Users: - description: > - Create and manage users that have access to InfluxDB OSS v2 organizations - and resources. + description: | + Create and manage users that have access to InfluxDB OSS v2 organizations and resources. + externalDocs: + description: Manage users + url: /influxdb/v2/users/ x-related: - title: Manage users href: /influxdb/v2/users/ - Variables: - description: > + description: | Create and manage variables for use in InfluxDB OSS v2 dashboards. - Views: - description: > + description: | Manage cell views within InfluxDB OSS v2 dashboards. - Write data: - description: > - Write time series data to InfluxDB OSS v2 buckets in line protocol format - using the `/api/v2/write` endpoint. + description: | + Write time series data to InfluxDB OSS v2 buckets in line protocol format using the `/api/v2/write` endpoint. + externalDocs: + description: Write data + url: /influxdb/v2/write-data/ x-related: - title: Write data href: /influxdb/v2/write-data/ - Write data (v1-compatible): - description: > - Write data to InfluxDB OSS v2 using the v1-compatible `/write` endpoint - with line protocol. + description: | + Write data to InfluxDB OSS v2 using the v1-compatible `/write` endpoint with line protocol. diff --git a/api-docs/influxdb3/cloud-dedicated/management/tags.yml b/api-docs/influxdb3/cloud-dedicated/management/tags.yml index 8b72ce8ce..81a7cb975 100644 --- a/api-docs/influxdb3/cloud-dedicated/management/tags.yml +++ b/api-docs/influxdb3/cloud-dedicated/management/tags.yml @@ -1,8 +1,10 @@ tags: Database tokens: - description: > - Create and manage database tokens that authorize read and write access to - InfluxDB 3 Cloud Dedicated databases. + description: | + Create and manage database tokens that authorize read and write access to InfluxDB 3 Cloud Dedicated databases. + externalDocs: + description: Manage database tokens + url: /influxdb3/cloud-dedicated/admin/tokens/database/ x-related: - title: Manage database tokens href: /influxdb3/cloud-dedicated/admin/tokens/database/ @@ -10,11 +12,12 @@ tags: href: /influxdb3/cloud-dedicated/admin/tokens/database/delete/ - title: Authenticate Telegraf using tokens in your OS secret store href: https://github.com/influxdata/telegraf/tree/master/plugins/secretstores/os - Databases: - description: > - Create and manage databases in an InfluxDB 3 Cloud Dedicated cluster, - including setting retention periods and custom partition templates. + description: | + Create and manage databases in an InfluxDB 3 Cloud Dedicated cluster, including setting retention periods and custom partition templates. + externalDocs: + description: Manage databases + url: /influxdb3/cloud-dedicated/admin/databases/ x-related: - title: Manage databases href: /influxdb3/cloud-dedicated/admin/databases/ @@ -22,22 +25,24 @@ tags: href: /influxdb3/cloud-dedicated/admin/custom-partitions/ - title: Partition templates href: /influxdb3/cloud-dedicated/admin/custom-partitions/partition-templates/ - Quick start: x-traitTag: true - description: > - Get started creating a database, issuing tokens, and writing data with - the InfluxDB 3 Cloud Dedicated Management API. + description: | + Get started creating a database, issuing tokens, and writing data with the InfluxDB 3 Cloud Dedicated Management API. + externalDocs: + description: Get started with Cloud Dedicated + url: /influxdb3/cloud-dedicated/get-started/ x-related: - title: Get started with Cloud Dedicated href: /influxdb3/cloud-dedicated/get-started/ - title: Set up your cluster href: /influxdb3/cloud-dedicated/get-started/setup/ - Tables: - description: > - Manage tables in an InfluxDB 3 Cloud Dedicated database, including - creating tables with custom column schemas. + description: | + Manage tables in an InfluxDB 3 Cloud Dedicated database, including creating tables with custom column schemas. + externalDocs: + description: Manage tables + url: /influxdb3/cloud-dedicated/admin/tables/ x-related: - title: Manage tables href: /influxdb3/cloud-dedicated/admin/tables/ diff --git a/api-docs/influxdb3/cloud-dedicated/tags.yml b/api-docs/influxdb3/cloud-dedicated/tags.yml index 827d593f7..8f85c1fce 100644 --- a/api-docs/influxdb3/cloud-dedicated/tags.yml +++ b/api-docs/influxdb3/cloud-dedicated/tags.yml @@ -26,6 +26,9 @@ tags: ### InfluxDB v1 compatibility The HTTP API [`/write` endpoint](#operation/PostLegacyWrite) and [`/query` endpoint](#operation/GetLegacyQuery) work with InfluxDB 1.x username/password [authentication schemes](#section/Authentication/) and existing InfluxDB 1.x tools and code. + externalDocs: + description: Get started querying InfluxDB + url: /influxdb3/cloud-dedicated/get-started/query/ x-related: - title: Get started querying InfluxDB href: /influxdb3/cloud-dedicated/get-started/query/ @@ -35,7 +38,6 @@ tags: href: /influxdb3/cloud-dedicated/guides/api-compatibility/v2/ - title: Use the v1 HTTP API with Cloud Dedicated href: /influxdb3/cloud-dedicated/guides/api-compatibility/v1/ - Authentication: x-traitTag: true description: | @@ -46,63 +48,50 @@ tags: - [Basic authentication](#section/Authentication/BasicAuthentication) - [Querystring authentication](#section/Authentication/QuerystringAuthentication) - Common parameters: x-traitTag: true - description: > - Common query parameters used by InfluxDB 3 Cloud Dedicated API endpoints, - including the required `database` or `db` parameter. - + description: | + Common query parameters used by InfluxDB 3 Cloud Dedicated API endpoints, including the required `database` or `db` parameter. Headers: x-traitTag: true - description: > - Standard HTTP request headers used by InfluxDB 3 Cloud Dedicated API - endpoints, including `Accept`, `Authorization`, `Content-Length`, and - `Content-Type`. - + description: | + Standard HTTP request headers used by InfluxDB 3 Cloud Dedicated API endpoints, including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. Ping: - description: > + description: | Check the availability of the InfluxDB 3 Cloud Dedicated instance. - Query data: - description: > - Query data stored in InfluxDB 3 Cloud Dedicated using InfluxQL via the - v1-compatible `/query` endpoint. Use Flight+gRPC for SQL or InfluxQL - queries with Arrow format output. + description: | + Query data stored in InfluxDB 3 Cloud Dedicated using InfluxQL via the v1-compatible `/query` endpoint. Use Flight+gRPC for SQL or InfluxQL queries with Arrow format output. + externalDocs: + description: Get started querying InfluxDB + url: /influxdb3/cloud-dedicated/get-started/query/ x-related: - title: Get started querying InfluxDB href: /influxdb3/cloud-dedicated/get-started/query/ - title: Execute queries href: /influxdb3/cloud-dedicated/query-data/execute-queries/ - Quick start: x-traitTag: true - description: > - Get started authenticating, creating a database, and writing and querying - data with the InfluxDB 3 Cloud Dedicated API. - + description: | + Get started authenticating, creating a database, and writing and querying data with the InfluxDB 3 Cloud Dedicated API. Response codes: x-traitTag: true - description: > - Standard HTTP status codes returned by InfluxDB 3 Cloud Dedicated API - endpoints and their meanings. - + description: | + Standard HTTP status codes returned by InfluxDB 3 Cloud Dedicated API endpoints and their meanings. System information endpoints: x-traitTag: true - description: > - Endpoints for retrieving system-level information about the InfluxDB 3 - Cloud Dedicated instance. - + description: | + Endpoints for retrieving system-level information about the InfluxDB 3 Cloud Dedicated instance. Usage: x-traitTag: true - description: > + description: | Retrieve usage metrics for an InfluxDB 3 Cloud Dedicated instance. - Write data: - description: > - Write time series data to InfluxDB 3 Cloud Dedicated databases using the - v2-compatible `/api/v2/write` endpoint or the v1-compatible `/write` - endpoint with line protocol. + description: | + Write time series data to InfluxDB 3 Cloud Dedicated databases using the v2-compatible `/api/v2/write` endpoint or the v1-compatible `/write` endpoint with line protocol. + externalDocs: + description: Write data + url: /influxdb3/cloud-dedicated/write-data/ x-related: - title: Write data href: /influxdb3/cloud-dedicated/write-data/ diff --git a/api-docs/influxdb3/cloud-serverless/tags.yml b/api-docs/influxdb3/cloud-serverless/tags.yml index 285821eea..a75252969 100644 --- a/api-docs/influxdb3/cloud-serverless/tags.yml +++ b/api-docs/influxdb3/cloud-serverless/tags.yml @@ -41,6 +41,9 @@ tags: ### InfluxDB v1 compatibility The `/write` and `/query` endpoints work with InfluxDB 1.x username/password authentication and existing InfluxDB 1.x tools and code. + externalDocs: + description: Write data + url: /influxdb3/cloud-serverless/write-data/ x-related: - title: Write data href: /influxdb3/cloud-serverless/write-data/ @@ -54,7 +57,6 @@ tags: href: /influxdb3/cloud-serverless/guides/api-compatibility/v2/ - title: Use the v1 HTTP API with Cloud Serverless href: /influxdb3/cloud-serverless/guides/api-compatibility/v1/ - Authentication: x-traitTag: true description: | @@ -62,249 +64,150 @@ tags: - Token authentication - Basic authentication - Authorizations (API tokens): - description: > - Create and manage API token authorizations that grant read and write - permissions to InfluxDB 3 Cloud Serverless organization resources. + description: | + Create and manage API token authorizations that grant read and write permissions to InfluxDB 3 Cloud Serverless organization resources. + externalDocs: + description: Manage API tokens + url: /influxdb3/cloud-serverless/security/tokens/ x-related: - title: Manage API tokens href: /influxdb3/cloud-serverless/security/tokens/ - Bucket Schemas: - description: > - Manage explicit schemas for InfluxDB 3 Cloud Serverless buckets to - enforce column names and data types. - + description: | + Manage explicit schemas for InfluxDB 3 Cloud Serverless buckets to enforce column names and data types. Buckets: - description: > - Create and manage named storage locations (buckets) in InfluxDB 3 Cloud - Serverless, each with a configurable retention period. + description: | + Create and manage named storage locations (buckets) in InfluxDB 3 Cloud Serverless, each with a configurable retention period. + externalDocs: + description: Manage buckets + url: /influxdb3/cloud-serverless/admin/buckets/ x-related: - title: Manage buckets href: /influxdb3/cloud-serverless/admin/buckets/ - Cells: x-traitTag: true - description: > - Manage cells within dashboards. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Manage cells within dashboards. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Checks: x-traitTag: true - description: > - Create and manage monitoring checks that query data and generate - notification statuses. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage monitoring checks that query data and generate notification statuses. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Common parameters: x-traitTag: true - description: > - Common query parameters used by InfluxDB 3 Cloud Serverless API - endpoints, including `bucket`, `bucketID`, `org`, and `orgID`. - + description: | + Common query parameters used by InfluxDB 3 Cloud Serverless API endpoints, including `bucket`, `bucketID`, `org`, and `orgID`. Config: x-traitTag: true - description: > - Retrieve configuration information for an InfluxDB instance. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Retrieve configuration information for an InfluxDB instance. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Dashboards: x-traitTag: true - description: > - Create and manage dashboards. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage dashboards. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). DBRPs: x-traitTag: true - description: > - Manage database and retention policy (DBRP) mappings. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Manage database and retention policy (DBRP) mappings. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Delete: x-traitTag: true - description: > - Delete time series data from a bucket by specifying a time range and - optional predicate. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Delete time series data from a bucket by specifying a time range and optional predicate. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Headers: x-traitTag: true - description: > - Standard HTTP request headers used by InfluxDB 3 Cloud Serverless API - endpoints, including `Accept`, `Authorization`, `Content-Length`, and - `Content-Type`. - + description: | + Standard HTTP request headers used by InfluxDB 3 Cloud Serverless API endpoints, including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. Invokable Scripts: x-traitTag: true - description: > - Store, manage, and execute custom Flux scripts. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Store, manage, and execute custom Flux scripts. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Labels: x-traitTag: true - description: > - Create and manage labels for organizing resources. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage labels for organizing resources. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Legacy Authorizations: x-traitTag: true - description: > - Manage legacy (v1-compatible) authorization credentials. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Manage legacy (v1-compatible) authorization credentials. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Limits: - description: > - Retrieve rate limits and usage quotas for an InfluxDB 3 Cloud Serverless - organization. - + description: | + Retrieve rate limits and usage quotas for an InfluxDB 3 Cloud Serverless organization. NotificationEndpoints: x-traitTag: true - description: > - Create and manage notification endpoints that receive alert notifications. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage notification endpoints that receive alert notifications. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). NotificationRules: x-traitTag: true - description: > - Create and manage notification rules that define when and how - notifications are sent to endpoints. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage notification rules that define when and how notifications are sent to endpoints. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Organizations: - description: > - View and manage InfluxDB 3 Cloud Serverless organizations, which are - workspaces that group users, buckets, and resources. + description: | + View and manage InfluxDB 3 Cloud Serverless organizations, which are workspaces that group users, buckets, and resources. + externalDocs: + description: View and manage organizations + url: /influxdb3/cloud-serverless/admin/ x-related: - title: View and manage organizations href: /influxdb3/cloud-serverless/admin/ - Pagination: x-traitTag: true - description: > - Query parameters for paginating results from list operations in the - InfluxDB 3 Cloud Serverless API. - + description: | + Query parameters for paginating results from list operations in the InfluxDB 3 Cloud Serverless API. Ping: x-traitTag: true - description: > - Check the availability of an InfluxDB instance. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Check the availability of an InfluxDB instance. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Query data: - description: > - Query data stored in InfluxDB 3 Cloud Serverless using InfluxQL via the - v1-compatible `/query` endpoint, or using SQL and InfluxQL via - Flight+gRPC clients. + description: | + Query data stored in InfluxDB 3 Cloud Serverless using InfluxQL via the v1-compatible `/query` endpoint, or using SQL and InfluxQL via Flight+gRPC clients. + externalDocs: + description: Get started querying InfluxDB + url: /influxdb3/cloud-serverless/get-started/query/ x-related: - title: Get started querying InfluxDB href: /influxdb3/cloud-serverless/get-started/query/ - title: Execute queries href: /influxdb3/cloud-serverless/query-data/execute-queries/ - Quick start: x-traitTag: true - description: > - Get started writing and querying data with the InfluxDB 3 Cloud - Serverless API. - + description: | + Get started writing and querying data with the InfluxDB 3 Cloud Serverless API. Resources: x-traitTag: true - description: > - Retrieve a list of top-level resource types available in the API. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Retrieve a list of top-level resource types available in the API. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Response codes: x-traitTag: true - description: > - Standard HTTP status codes returned by InfluxDB 3 Cloud Serverless API - endpoints and their meanings. - + description: | + Standard HTTP status codes returned by InfluxDB 3 Cloud Serverless API endpoints and their meanings. Routes: x-traitTag: true - description: > - Retrieve top-level routes for the InfluxDB API. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Retrieve top-level routes for the InfluxDB API. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Rules: x-traitTag: true - description: > - Manage notification rules. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Manage notification rules. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Secrets: x-traitTag: true - description: > - Create and manage secrets (key-value pairs) for use in Flux scripts - and tasks. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage secrets (key-value pairs) for use in Flux scripts and tasks. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Security and access endpoints: x-traitTag: true - description: > - Endpoints for managing authentication and access control. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Endpoints for managing authentication and access control. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Setup: x-traitTag: true - description: > - Configure an initial InfluxDB instance, including creating the initial - user, organization, and bucket. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Configure an initial InfluxDB instance, including creating the initial user, organization, and bucket. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Signin: x-traitTag: true - description: > - Create a user session by signing in with username and password - credentials. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create a user session by signing in with username and password credentials. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Signout: x-traitTag: true - description: > - End a user session by signing out. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + End a user session by signing out. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Supported operations: x-traitTag: true description: | @@ -317,84 +220,47 @@ tags: | **Read** | `GET` | Retrieve a resource or list resources. | | **Update** | `PUT`, `PATCH` | Replace or modify an existing resource. | | **Delete** | `DELETE` | Remove a resource. | - System information endpoints: x-traitTag: true - description: > - Endpoints for retrieving system-level information about an InfluxDB - instance. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Endpoints for retrieving system-level information about an InfluxDB instance. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Tasks: x-traitTag: true - description: > - Schedule and manage Flux tasks that process and transform data on a - recurring basis. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Schedule and manage Flux tasks that process and transform data on a recurring basis. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Telegraf Plugins: x-traitTag: true - description: > - Retrieve available Telegraf plugin configuration templates. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Retrieve available Telegraf plugin configuration templates. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Telegrafs: x-traitTag: true - description: > - Create and manage Telegraf agent configurations that collect and write - data to InfluxDB. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage Telegraf agent configurations that collect and write data to InfluxDB. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Templates: x-traitTag: true - description: > - Export and apply InfluxDB templates, and manage template stacks. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Export and apply InfluxDB templates, and manage template stacks. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Usage: - description: > - Retrieve usage metrics and cardinality data for an InfluxDB 3 Cloud - Serverless organization. - + description: | + Retrieve usage metrics and cardinality data for an InfluxDB 3 Cloud Serverless organization. Users: x-traitTag: true - description: > - View specific users that are members of your organization. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + View specific users that are members of your organization. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Variables: x-traitTag: true - description: > - Create and manage variables for use in dashboards. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Create and manage variables for use in dashboards. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Views: x-traitTag: true - description: > - Manage cell views within dashboards. - This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is - not supported or recommended for use with InfluxDB Cloud Serverless - (powered by the InfluxDB 3 storage engine). - + description: | + Manage cell views within dashboards. This is an InfluxDB Cloud (TSM) endpoint that may be accessible but is not supported or recommended for use with InfluxDB Cloud Serverless (powered by the InfluxDB 3 storage engine). Write data: - description: > - Write time series data to InfluxDB 3 Cloud Serverless buckets using the - v2-compatible `/api/v2/write` endpoint or the v1-compatible `/write` - endpoint with line protocol. + description: | + Write time series data to InfluxDB 3 Cloud Serverless buckets using the v2-compatible `/api/v2/write` endpoint or the v1-compatible `/write` endpoint with line protocol. + externalDocs: + description: Write data + url: /influxdb3/cloud-serverless/write-data/ x-related: - title: Write data href: /influxdb3/cloud-serverless/write-data/ diff --git a/api-docs/influxdb3/clustered/management/tags.yml b/api-docs/influxdb3/clustered/management/tags.yml index 8093f98f0..2454ffa99 100644 --- a/api-docs/influxdb3/clustered/management/tags.yml +++ b/api-docs/influxdb3/clustered/management/tags.yml @@ -1,8 +1,10 @@ tags: Database tokens: - description: > - Create and manage database tokens that authorize read and write access to - InfluxDB 3 Clustered databases. + description: | + Create and manage database tokens that authorize read and write access to InfluxDB 3 Clustered databases. + externalDocs: + description: Manage database tokens + url: /influxdb3/clustered/admin/tokens/database/ x-related: - title: Manage database tokens href: /influxdb3/clustered/admin/tokens/database/ @@ -10,30 +12,33 @@ tags: href: /influxdb3/clustered/admin/tokens/database/delete/ - title: Authenticate Telegraf using tokens in your OS secret store href: https://github.com/influxdata/telegraf/tree/master/plugins/secretstores/os - Databases: - description: > - Create and manage databases in an InfluxDB 3 Clustered cluster, including - setting retention periods and custom partition templates. + description: | + Create and manage databases in an InfluxDB 3 Clustered cluster, including setting retention periods and custom partition templates. + externalDocs: + description: Manage databases + url: /influxdb3/clustered/admin/databases/ x-related: - title: Manage databases href: /influxdb3/clustered/admin/databases/ - title: Custom partitions href: /influxdb3/clustered/admin/custom-partitions/ - Quick start: x-traitTag: true - description: > - Get started creating a database, issuing tokens, and writing data with - the InfluxDB 3 Clustered Management API. + description: | + Get started creating a database, issuing tokens, and writing data with the InfluxDB 3 Clustered Management API. + externalDocs: + description: Get started with Clustered + url: /influxdb3/clustered/get-started/ x-related: - title: Get started with Clustered href: /influxdb3/clustered/get-started/ - Tables: - description: > - Manage tables in an InfluxDB 3 Clustered database, including creating - tables with custom column schemas. + description: | + Manage tables in an InfluxDB 3 Clustered database, including creating tables with custom column schemas. + externalDocs: + description: Manage tables + url: /influxdb3/clustered/admin/tables/ x-related: - title: Manage tables href: /influxdb3/clustered/admin/tables/ diff --git a/api-docs/influxdb3/clustered/tags.yml b/api-docs/influxdb3/clustered/tags.yml index ea26eea93..989684104 100644 --- a/api-docs/influxdb3/clustered/tags.yml +++ b/api-docs/influxdb3/clustered/tags.yml @@ -26,6 +26,9 @@ tags: ### InfluxDB v1 compatibility The HTTP API [`/write` endpoint](#operation/PostLegacyWrite) and [`/query` endpoint](#operation/GetLegacyQuery) work with InfluxDB 1.x username/password [authentication schemes](#section/Authentication/) and existing InfluxDB 1.x tools and code. + externalDocs: + description: Get started querying InfluxDB + url: /influxdb3/clustered/get-started/query/ x-related: - title: Get started querying InfluxDB href: /influxdb3/clustered/get-started/query/ @@ -35,7 +38,6 @@ tags: href: /influxdb3/clustered/guides/api-compatibility/v2/ - title: Use the v1 HTTP API with Clustered href: /influxdb3/clustered/guides/api-compatibility/v1/ - Authentication: x-traitTag: true description: | @@ -46,62 +48,50 @@ tags: - [Basic authentication](#section/Authentication/BasicAuthentication) - [Querystring authentication](#section/Authentication/QuerystringAuthentication) - Common parameters: x-traitTag: true - description: > - Common query parameters used by InfluxDB 3 Clustered API endpoints, - including the required `database` or `db` parameter. - + description: | + Common query parameters used by InfluxDB 3 Clustered API endpoints, including the required `database` or `db` parameter. Headers: x-traitTag: true - description: > - Standard HTTP request headers used by InfluxDB 3 Clustered API endpoints, - including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. - + description: | + Standard HTTP request headers used by InfluxDB 3 Clustered API endpoints, including `Accept`, `Authorization`, `Content-Length`, and `Content-Type`. Ping: - description: > + description: | Check the availability of an InfluxDB 3 Clustered instance. - Query data: - description: > - Query data stored in InfluxDB 3 Clustered using InfluxQL via the - v1-compatible `/query` endpoint. Use Flight+gRPC for SQL or InfluxQL - queries with Arrow format output. + description: | + Query data stored in InfluxDB 3 Clustered using InfluxQL via the v1-compatible `/query` endpoint. Use Flight+gRPC for SQL or InfluxQL queries with Arrow format output. + externalDocs: + description: Get started querying InfluxDB + url: /influxdb3/clustered/get-started/query/ x-related: - title: Get started querying InfluxDB href: /influxdb3/clustered/get-started/query/ - title: Execute queries href: /influxdb3/clustered/query-data/execute-queries/ - Quick start: x-traitTag: true - description: > - Get started authenticating, creating a database, and writing and querying - data with the InfluxDB 3 Clustered API. - + description: | + Get started authenticating, creating a database, and writing and querying data with the InfluxDB 3 Clustered API. Response codes: x-traitTag: true - description: > - Standard HTTP status codes returned by InfluxDB 3 Clustered API endpoints - and their meanings. - + description: | + Standard HTTP status codes returned by InfluxDB 3 Clustered API endpoints and their meanings. System information endpoints: x-traitTag: true - description: > - Endpoints for retrieving system-level information about the InfluxDB 3 - Clustered instance. - + description: | + Endpoints for retrieving system-level information about the InfluxDB 3 Clustered instance. Usage: x-traitTag: true - description: > + description: | Retrieve usage metrics for an InfluxDB 3 Clustered instance. - Write data: - description: > - Write time series data to InfluxDB 3 Clustered databases using the - v2-compatible `/api/v2/write` endpoint or the v1-compatible `/write` - endpoint with line protocol. + description: | + Write time series data to InfluxDB 3 Clustered databases using the v2-compatible `/api/v2/write` endpoint or the v1-compatible `/write` endpoint with line protocol. + externalDocs: + description: Write data + url: /influxdb3/clustered/write-data/ x-related: - title: Write data href: /influxdb3/clustered/write-data/ diff --git a/api-docs/influxdb3/core/tags.yml b/api-docs/influxdb3/core/tags.yml index 01af6fc2c..83b4cb4d6 100644 --- a/api-docs/influxdb3/core/tags.yml +++ b/api-docs/influxdb3/core/tags.yml @@ -9,7 +9,6 @@ tags: - [Basic authentication](#section/Authentication/BasicAuthentication) - [Querystring authentication](#section/Authentication/QuerystringAuthentication) - Cache distinct values: description: | The Distinct Value Cache (DVC) lets you cache distinct @@ -21,10 +20,12 @@ tags: values to cache, the maximum number of distinct value combinations to cache, and the maximum age of cached values. A DVC is associated with a table, which can have multiple DVCs. + externalDocs: + description: Manage the Distinct Value Cache + url: /influxdb3/core/admin/distinct-value-cache/ x-related: - title: Manage the Distinct Value Cache href: /influxdb3/core/admin/distinct-value-cache/ - Cache last value: description: | The Last Value Cache (LVC) lets you cache the most recent @@ -37,10 +38,12 @@ tags: what fields to cache, what tags to use to identify each series, and the number of values to cache for each unique series. An LVC is associated with a table, which can have multiple LVCs. + externalDocs: + description: Manage the Last Value Cache + url: /influxdb3/core/admin/last-value-cache/ x-related: - title: Manage the Last Value Cache href: /influxdb3/core/admin/last-value-cache/ - Migrate from InfluxDB v1 or v2: x-traitTag: true description: | @@ -55,14 +58,15 @@ tags: - [Migrate from InfluxDB v2](/influxdb3/core/guides/migrate/influxdb-2x/) - For users migrating from InfluxDB 2.x or Cloud - [Use compatibility APIs to write data](/influxdb3/core/write-data/http-api/compatibility-apis/) - v1 and v2 write endpoints - [Use the v1 HTTP query API](/influxdb3/core/query-data/execute-queries/influxdb-v1-api/) - InfluxQL queries via HTTP - Database: - description: > + description: | Create, list, and delete databases in InfluxDB 3 Core. + externalDocs: + description: Manage databases + url: /influxdb3/core/admin/databases/ x-related: - title: Manage databases href: /influxdb3/core/admin/databases/ - Headers and parameters: x-traitTag: true description: | @@ -89,24 +93,27 @@ tags: | `Authorization` | string | The [authorization scheme and credential](/influxdb/version/api/authentication/). | | `Content-Length` | integer | The size of the entity-body, in bytes. | | `Content-Type` | string | The format of the data in the request body. | - Processing engine: description: | Manage Processing engine triggers, test plugins, and send requests to trigger On Request plugins. InfluxDB 3 Core provides the InfluxDB 3 processing engine, an embedded Python VM that can dynamically load and trigger Python plugins in response to events in your database. Use Processing engine plugins and triggers to run code and perform tasks for different database events. + externalDocs: + description: Processing engine and Python plugins + url: /influxdb3/core/processing-engine/ x-related: - title: Processing engine and Python plugins href: /influxdb3/core/processing-engine/ - Query data: - description: > + description: | Query data stored in InfluxDB 3 Core using SQL or InfluxQL. + externalDocs: + description: Query data + url: /influxdb3/core/query-data/ x-related: - title: Query data href: /influxdb3/core/query-data/ - Quick start: x-traitTag: true description: | @@ -152,27 +159,27 @@ tags: ``` For more information about using InfluxDB 3 Core, see the [Get started](/influxdb3/core/get-started/) guide. - Server information: - description: > - Retrieve server metrics, health status, and version information for - InfluxDB 3 Core. - + description: | + Retrieve server metrics, health status, and version information for InfluxDB 3 Core. Table: - description: > + description: | Manage table schemas in an InfluxDB 3 Core database. + externalDocs: + description: Manage tables + url: /influxdb3/core/admin/tables/ x-related: - title: Manage tables href: /influxdb3/core/admin/tables/ - Auth token: - description: > - Create and manage tokens used for authenticating and authorizing access - to InfluxDB 3 Core resources. + description: | + Create and manage tokens used for authenticating and authorizing access to InfluxDB 3 Core resources. + externalDocs: + description: Manage tokens + url: /influxdb3/core/admin/tokens/ x-related: - title: Manage tokens href: /influxdb3/core/admin/tokens/ - Write data: description: | Write data to InfluxDB 3 Core using line protocol format. @@ -194,6 +201,9 @@ tags: | **Default** | Nanosecond | Nanosecond | **Auto** (guessed) | All timestamps are stored internally as nanoseconds. + externalDocs: + description: Write data using HTTP APIs + url: /influxdb3/core/write-data/http-api/ x-related: - title: Write data using HTTP APIs href: /influxdb3/core/write-data/http-api/ diff --git a/api-docs/influxdb3/enterprise/tags.yml b/api-docs/influxdb3/enterprise/tags.yml index 7cac19867..0a7f893a7 100644 --- a/api-docs/influxdb3/enterprise/tags.yml +++ b/api-docs/influxdb3/enterprise/tags.yml @@ -9,7 +9,6 @@ tags: - [Basic authentication](#section/Authentication/BasicAuthentication) - [Querystring authentication](#section/Authentication/QuerystringAuthentication) - Cache data: description: | Manage the in-memory cache. @@ -38,19 +37,23 @@ tags: what fields to cache, what tags to use to identify each series, and the number of values to cache for each unique series. An LVC is associated with a table, which can have multiple LVCs. + externalDocs: + description: Manage the Distinct Value Cache + url: /influxdb3/enterprise/admin/distinct-value-cache/ x-related: - title: Manage the Distinct Value Cache href: /influxdb3/enterprise/admin/distinct-value-cache/ - title: Manage the Last Value Cache href: /influxdb3/enterprise/admin/last-value-cache/ - Database: - description: > + description: | Create, list, and delete databases in InfluxDB 3 Enterprise. + externalDocs: + description: Manage databases + url: /influxdb3/enterprise/admin/databases/ x-related: - title: Manage databases href: /influxdb3/enterprise/admin/databases/ - Headers and parameters: x-traitTag: true description: | @@ -77,24 +80,27 @@ tags: | `Authorization` | string | The authorization scheme and credential. | | `Content-Length` | integer | The size of the entity-body, in bytes. | | `Content-Type` | string | The format of the data in the request body. | - Processing engine: description: | Manage Processing engine triggers, test plugins, and send requests to trigger On Request plugins. InfluxDB 3 Enterprise provides the InfluxDB 3 processing engine, an embedded Python VM that can dynamically load and trigger Python plugins in response to events in your database. Use Processing engine plugins and triggers to run code and perform tasks for different database events. + externalDocs: + description: Processing engine and Python plugins + url: /influxdb3/enterprise/processing-engine/ x-related: - title: Processing engine and Python plugins href: /influxdb3/enterprise/processing-engine/ - Query data: - description: > + description: | Query data stored in InfluxDB 3 Enterprise using SQL or InfluxQL. + externalDocs: + description: Query data + url: /influxdb3/enterprise/query-data/ x-related: - title: Query data href: /influxdb3/enterprise/query-data/ - Quick start: x-traitTag: true description: | @@ -140,27 +146,27 @@ tags: ``` For more information, see the [Get started](/influxdb3/enterprise/get-started/) guide. - Server information: - description: > - Retrieve server metrics, health status, and version information for - InfluxDB 3 Enterprise. - + description: | + Retrieve server metrics, health status, and version information for InfluxDB 3 Enterprise. Table: - description: > + description: | Manage table schemas in an InfluxDB 3 Enterprise database. + externalDocs: + description: Manage tables + url: /influxdb3/enterprise/admin/tables/ x-related: - title: Manage tables href: /influxdb3/enterprise/admin/tables/ - Token: - description: > - Create and manage tokens used for authenticating and authorizing access - to InfluxDB 3 Enterprise resources. + description: | + Create and manage tokens used for authenticating and authorizing access to InfluxDB 3 Enterprise resources. + externalDocs: + description: Manage tokens + url: /influxdb3/enterprise/admin/tokens/ x-related: - title: Manage tokens href: /influxdb3/enterprise/admin/tokens/ - Write data: description: | Write data to InfluxDB 3 Enterprise using line protocol format. @@ -182,6 +188,9 @@ tags: | **Default** | Nanosecond | Nanosecond | **Auto** (guessed) | All timestamps are stored internally as nanoseconds. + externalDocs: + description: Write data using HTTP APIs + url: /influxdb3/enterprise/write-data/http-api/ x-related: - title: Write data using HTTP APIs href: /influxdb3/enterprise/write-data/http-api/ diff --git a/api-docs/scripts/dist/generate-openapi-articles.js b/api-docs/scripts/dist/generate-openapi-articles.js index 2b1bc7adb..ff08d584c 100644 --- a/api-docs/scripts/dist/generate-openapi-articles.js +++ b/api-docs/scripts/dist/generate-openapi-articles.js @@ -3,27 +3,20 @@ /** * Generate OpenAPI Articles Script * - * Generates Hugo data files and content pages from OpenAPI specifications - * for all InfluxDB products. + * Processes OpenAPI specs for Hugo-native API documentation. This script + * expects specs to already be fetched (via getswagger.sh) and post-processed + * (via post-process-specs.ts) before it runs. * - * Products are auto-discovered by scanning api-docs/ for .config.yml files. - * Hugo paths, menu keys, and static file names are derived from directory - * structure and existing Hugo frontmatter. - * - * This script: - * 1. Discovers products from .config.yml files - * 2. Cleans output directories (unless --no-clean) - * 3. Transforms documentation links in specs - * 4. Copies specs to static directory for download - * 5. Generates tag-based data fragments (YAML and JSON) - * 6. Generates Hugo content pages from article data + * Modes: + * - Default: copy specs to static/ + generate Hugo article pages + * - --static-only: copy specs to static/ only (no article generation) * * Usage: - * node generate-openapi-articles.js # Clean and generate all products - * node generate-openapi-articles.js influxdb3-core # Clean and generate single product + * node generate-openapi-articles.js # Full generation (static + articles) + * node generate-openapi-articles.js cloud-v2 # Single product + * node generate-openapi-articles.js --static-only # Copy specs to static/ only * node generate-openapi-articles.js --no-clean # Generate without cleaning * node generate-openapi-articles.js --dry-run # Preview what would be cleaned - * node generate-openapi-articles.js --skip-fetch # Skip getswagger.sh fetch step * node generate-openapi-articles.js --validate-links # Validate documentation links * * @module generate-openapi-articles @@ -62,37 +55,32 @@ var __importStar = (this && this.__importStar) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -exports.LINK_PATTERN = exports.MARKDOWN_FIELDS = void 0; -exports.discoverProducts = discoverProducts; +exports.LINK_PATTERN = exports.MARKDOWN_FIELDS = exports.productConfigs = void 0; exports.processProduct = processProduct; -exports.processApiSection = processApiSection; +exports.generateDataFromOpenAPI = generateDataFromOpenAPI; +exports.generatePagesFromArticleData = generatePagesFromArticleData; +exports.deriveProductPath = deriveProductPath; exports.transformDocLinks = transformDocLinks; exports.validateDocLinks = validateDocLinks; exports.resolveContentPath = resolveContentPath; -exports.deriveStaticDirName = deriveStaticDirName; -exports.getSectionSlug = getSectionSlug; -exports.parseApiEntry = parseApiEntry; -exports.readMenuKey = readMenuKey; -const child_process_1 = require("child_process"); const path = __importStar(require("path")); const fs = __importStar(require("fs")); // Import the OpenAPI to Hugo converter const openapiPathsToHugo = require('./openapi-paths-to-hugo-data/index.js'); -// --------------------------------------------------------------------------- -// Constants and CLI flags -// --------------------------------------------------------------------------- +// Calculate the relative paths const DOCS_ROOT = '.'; -const API_DOCS_ROOT = 'api-docs'; +// Read resolved specs from _build/ (written by post-process-specs.ts). +// Source specs in api-docs/ are never read directly by this script. +const API_DOCS_ROOT = 'api-docs/_build'; +// CLI flags const validateLinks = process.argv.includes('--validate-links'); -const skipFetch = process.argv.includes('--skip-fetch'); +const staticOnly = process.argv.includes('--static-only'); const noClean = process.argv.includes('--no-clean'); const dryRun = process.argv.includes('--dry-run'); -// --------------------------------------------------------------------------- -// Utility functions -// --------------------------------------------------------------------------- /** - * Load products with API paths from data/products.yml. - * Returns a map of alt_link_key to API path for alt_links generation. + * Load products with API paths from data/products.yml + * Returns a map of alt_link_key to API path for alt_links generation + * The alt_link_key matches what the Hugo product-selector template expects */ function loadApiProducts() { const yaml = require('js-yaml'); @@ -104,294 +92,109 @@ function loadApiProducts() { const productsContent = fs.readFileSync(productsFile, 'utf8'); const products = yaml.load(productsContent); const apiProducts = new Map(); - for (const [, product] of Object.entries(products)) { + for (const [key, product] of Object.entries(products)) { if (product.api_path && product.alt_link_key) { + // Use alt_link_key as the key (matches Hugo template expectations) apiProducts.set(product.alt_link_key, product.api_path); } } return apiProducts; } +// Load API products at module initialization const apiProductsMap = loadApiProducts(); -/** Execute a shell command and handle errors */ -function execCommand(command, description) { - try { - if (description) { - console.log(`\n${description}...`); - } - console.log(`Executing: ${command}\n`); - (0, child_process_1.execSync)(command, { stdio: 'inherit' }); - } - catch (error) { - console.error(`\nโŒ Error executing command: ${command}`); - if (error instanceof Error) { - console.error(error.message); - } - process.exit(1); - } -} -// --------------------------------------------------------------------------- -// Auto-discovery functions -// --------------------------------------------------------------------------- /** - * Recursively find all .config.yml files under api-docs/. - * Excludes the root api-docs/.config.yml and internal directories. - */ -function findConfigFiles(rootDir) { - const configs = []; - const skipDirs = new Set([ - 'node_modules', - 'dist', - '_build', - 'scripts', - 'openapi', - ]); - function scanDir(dir, depth) { - if (depth > 5) - return; - let entries; - try { - entries = fs.readdirSync(dir, { withFileTypes: true }); - } - catch { - return; - } - for (const entry of entries) { - if (skipDirs.has(entry.name)) - continue; - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory()) { - scanDir(fullPath, depth + 1); - } - else if (entry.name === '.config.yml' && dir !== rootDir) { - configs.push(fullPath); - } - } - } - scanDir(rootDir, 0); - return configs.sort(); -} -/** - * Parse an API entry key like 'v3@3' into apiKey and version. - */ -function parseApiEntry(entry) { - const atIdx = entry.indexOf('@'); - if (atIdx === -1) { - return { apiKey: entry, version: '0' }; - } - return { - apiKey: entry.substring(0, atIdx), - version: entry.substring(atIdx + 1), - }; -} -/** - * Determine Hugo section slug from API key. - * 'management' โ†’ 'management-api', everything else โ†’ 'api'. - */ -function getSectionSlug(apiKey) { - if (apiKey === 'management') - return 'management-api'; - return 'api'; -} -/** - * Derive a clean static directory name from a product directory path. - * Replaces path separators and underscores with hyphens. + * Execute a shell command and handle errors * - * @example 'influxdb3/core' โ†’ 'influxdb3-core' - * @example 'enterprise_influxdb/v1' โ†’ 'enterprise-influxdb-v1' + * @param command - Command to execute + * @param description - Human-readable description of the command + * @throws Exits process with code 1 on error */ -function deriveStaticDirName(productDir) { - return productDir.replace(/[/_]/g, '-'); -} /** - * Read the cascade.product field from a product's _index.md frontmatter. - * This value serves as the Hugo menu key. - */ -function readMenuKey(pagesDir) { - const yaml = require('js-yaml'); - const indexFile = path.join(pagesDir, '_index.md'); - if (!fs.existsSync(indexFile)) { - console.warn(`โš ๏ธ Product index not found: ${indexFile}`); - return ''; - } - const content = fs.readFileSync(indexFile, 'utf8'); - const fmMatch = content.match(/^---\n([\s\S]*?)\n---/); - if (!fmMatch) - return ''; - try { - const fm = yaml.load(fmMatch[1]); - const cascade = fm.cascade; - if (cascade?.product) - return cascade.product; - // Fallback: first key of the menu map - if (fm.menu && typeof fm.menu === 'object') { - const keys = Object.keys(fm.menu); - if (keys.length > 0) - return keys[0]; - } - } - catch { - console.warn(`โš ๏ธ Could not parse frontmatter in ${indexFile}`); - } - return ''; -} -/** - * Check whether a hand-maintained api/_index.md already has a menu entry. - * If so, the generator should skip adding its own parent menu entry. + * Generate a clean static directory name from a product key. + * Handles the influxdb3_* products to avoid redundant 'influxdb-influxdb3' prefixes. * - * Only detects genuinely hand-maintained files โ€” files previously generated - * by this script (which have articleDataKey in frontmatter) are ignored, - * since they'll be regenerated during this run. + * @param productKey - Product identifier (e.g., 'cloud-v2', 'influxdb3_core') + * @returns Clean directory name (e.g., 'influxdb-cloud-v2', 'influxdb3-core') */ -function hasExistingApiMenu(pagesDir) { - const yaml = require('js-yaml'); - const apiIndex = path.join(pagesDir, 'api', '_index.md'); - if (!fs.existsSync(apiIndex)) - return false; - const content = fs.readFileSync(apiIndex, 'utf8'); - const fmMatch = content.match(/^---\n([\s\S]*?)\n---/); - if (!fmMatch) - return false; - try { - const fm = yaml.load(fmMatch[1]); - // Skip files generated by this script (they have articleDataKey) - if (fm.articleDataKey) - return false; - return !!fm.menu; - } - catch { - return false; +function getStaticDirName(productKey) { + // For influxdb3_* products, convert underscore to hyphen and don't add prefix + if (productKey.startsWith('influxdb3_')) { + return productKey.replace('_', '-'); } + // For other products, add 'influxdb-' prefix + return `influxdb-${productKey}`; } /** - * Discover all products by scanning api-docs/ for .config.yml files. - * Derives Hugo paths from directory structure and existing frontmatter. - */ -function discoverProducts() { - const yaml = require('js-yaml'); - const products = []; - const configFiles = findConfigFiles(API_DOCS_ROOT); - for (const configPath of configFiles) { - const configDir = path.dirname(configPath); - const productDir = path.relative(API_DOCS_ROOT, configDir); - let config; - try { - const raw = fs.readFileSync(configPath, 'utf8'); - config = yaml.load(raw); - } - catch (err) { - console.warn(`โš ๏ธ Could not parse ${configPath}: ${err}`); - continue; - } - if (!config.apis || Object.keys(config.apis).length === 0) { - continue; - } - const pagesDir = path.join(DOCS_ROOT, 'content', productDir); - const staticDirName = deriveStaticDirName(productDir); - const menuKey = readMenuKey(pagesDir); - const skipParentMenu = hasExistingApiMenu(pagesDir); - // Parse API entries, skipping compatibility specs - const apis = []; - for (const [entryKey, entry] of Object.entries(config.apis)) { - const { apiKey, version } = parseApiEntry(entryKey); - // Skip v1-compatibility entries (being removed in pipeline restructure) - if (apiKey.includes('compatibility')) - continue; - // Prefer post-processed spec from _build/ (has overlays and tag configs), - // fall back to source spec for standalone usage - const sourceSpec = path.join(configDir, entry.root); - const buildSpec = path.join(API_DOCS_ROOT, '_build', productDir, entry.root); - const specFile = fs.existsSync(buildSpec) ? buildSpec : sourceSpec; - const sectionSlug = getSectionSlug(apiKey); - apis.push({ apiKey, version, specFile, sectionSlug }); - } - if (apis.length === 0) - continue; - products.push({ - configDir, - productDir, - productName: config['x-influxdata-product-name'] || productDir, - pagesDir, - menuKey, - skipParentMenu, - staticDirName, - apis, - }); - } - return products; -} -// --------------------------------------------------------------------------- -// Cleanup functions -// --------------------------------------------------------------------------- -/** - * Get all paths that would be cleaned for a product. + * Get all paths that would be cleaned for a product * - * @param product - The product to clean - * @param allStaticDirNames - Names of all products (to avoid prefix collisions) + * @param productKey - Product identifier (e.g., 'influxdb3_core') + * @param config - Product configuration + * @returns Object with directories and files arrays */ -function getCleanupPaths(product, allStaticDirNames) { +function getCleanupPaths(productKey, config) { + const staticDirName = getStaticDirName(productKey); const staticPath = path.join(DOCS_ROOT, 'static/openapi'); const directories = []; const files = []; // Tag specs directory: static/openapi/{staticDirName}/ - const tagSpecsDir = path.join(staticPath, product.staticDirName); + const tagSpecsDir = path.join(staticPath, staticDirName); if (fs.existsSync(tagSpecsDir)) { directories.push(tagSpecsDir); } - // Article data directory: data/article_data/influxdb/{staticDirName}/ - const articleDataDir = path.join(DOCS_ROOT, `data/article_data/influxdb/${product.staticDirName}`); + // Article data directory: data/article_data/influxdb/{productKey}/ + const articleDataDir = path.join(DOCS_ROOT, `data/article_data/influxdb/${productKey}`); if (fs.existsSync(articleDataDir)) { directories.push(articleDataDir); } - // Content pages: content/{pagesDir}/{sectionSlug}/ for each API - for (const api of product.apis) { - const contentDir = path.join(product.pagesDir, api.sectionSlug); - if (fs.existsSync(contentDir)) { - directories.push(contentDir); - } + // Content pages directory: content/{pagesDir}/api/ + const contentApiDir = path.join(config.pagesDir, 'api'); + if (fs.existsSync(contentApiDir)) { + directories.push(contentApiDir); } - // Root spec files: static/openapi/{staticDirName}*.yml and .json - // Avoid matching files that belong to products with longer names - // (e.g., 'influxdb-cloud' should not match 'influxdb-cloud-dedicated-*.yml') - const longerPrefixes = allStaticDirNames.filter((n) => n !== product.staticDirName && n.startsWith(product.staticDirName + '-')); + // Root spec files: static/openapi/{staticDirName}-*.yml and .json if (fs.existsSync(staticPath)) { const staticFiles = fs.readdirSync(staticPath); + const pattern = new RegExp(`^${staticDirName}-.*\\.(yml|json)$`); staticFiles - .filter((f) => { - if (!f.startsWith(product.staticDirName)) - return false; - // Exclude files belonging to a longer-named product - for (const longer of longerPrefixes) { - if (f.startsWith(longer)) - return false; - } - return f.endsWith('.yml') || f.endsWith('.json'); - }) + .filter((f) => pattern.test(f)) .forEach((f) => { files.push(path.join(staticPath, f)); }); } return { directories, files }; } -/** Clean output directories for a product before regeneration. */ -function cleanProductOutputs(product, allStaticDirNames) { - const { directories, files } = getCleanupPaths(product, allStaticDirNames); +/** + * Clean output directories for a product before regeneration + * + * @param productKey - Product identifier + * @param config - Product configuration + */ +function cleanProductOutputs(productKey, config) { + const { directories, files } = getCleanupPaths(productKey, config); + // Remove directories recursively for (const dir of directories) { console.log(`๐Ÿงน Removing directory: ${dir}`); fs.rmSync(dir, { recursive: true, force: true }); } + // Remove individual files for (const file of files) { console.log(`๐Ÿงน Removing file: ${file}`); fs.unlinkSync(file); } const total = directories.length + files.length; if (total > 0) { - console.log(`โœ“ Cleaned ${directories.length} directories, ${files.length} files for ${product.staticDirName}`); + console.log(`โœ“ Cleaned ${directories.length} directories, ${files.length} files for ${productKey}`); } } -/** Display dry-run preview of what would be cleaned. */ -function showDryRunPreview(product, allStaticDirNames) { - const { directories, files } = getCleanupPaths(product, allStaticDirNames); - console.log(`\nDRY RUN: Would clean the following for ${product.staticDirName}:\n`); +/** + * Display dry-run preview of what would be cleaned + * + * @param productKey - Product identifier + * @param config - Product configuration + */ +function showDryRunPreview(productKey, config) { + const { directories, files } = getCleanupPaths(productKey, config); + console.log(`\nDRY RUN: Would clean the following for ${productKey}:\n`); if (directories.length > 0) { console.log('Directories to remove:'); directories.forEach((dir) => console.log(` - ${dir}`)); @@ -405,127 +208,180 @@ function showDryRunPreview(product, allStaticDirNames) { } console.log(`\nSummary: ${directories.length} directories, ${files.length} files would be removed`); } -// --------------------------------------------------------------------------- -// Link transformation -// --------------------------------------------------------------------------- -/** Fields that can contain markdown with links */ -const MARKDOWN_FIELDS = new Set(['description', 'summary']); -exports.MARKDOWN_FIELDS = MARKDOWN_FIELDS; -/** Link placeholder pattern */ -const LINK_PATTERN = /\/influxdb\/version\//g; -exports.LINK_PATTERN = LINK_PATTERN; /** - * Transform documentation links in OpenAPI spec markdown fields. - * Replaces `/influxdb/version/` with the actual product path. - */ -function transformDocLinks(spec, productPath) { - function transformValue(value) { - if (typeof value === 'string') { - return value.replace(LINK_PATTERN, `${productPath}/`); - } - if (Array.isArray(value)) { - return value.map(transformValue); - } - if (value !== null && typeof value === 'object') { - return transformObject(value); - } - return value; - } - function transformObject(obj) { - const result = {}; - for (const [key, value] of Object.entries(obj)) { - if (MARKDOWN_FIELDS.has(key) && typeof value === 'string') { - result[key] = value.replace(LINK_PATTERN, `${productPath}/`); - } - else if (value !== null && typeof value === 'object') { - result[key] = transformValue(value); - } - else { - result[key] = value; - } - } - return result; - } - return transformObject(spec); -} -/** - * Resolve a URL path to a content file path. + * Generate Hugo data files from OpenAPI specification * - * @example '/influxdb3/core/api/auth/' โ†’ 'content/influxdb3/core/api/auth/_index.md' + * @param specFile - Path to the OpenAPI spec file + * @param dataOutPath - Output path for OpenAPI path fragments + * @param articleOutPath - Output path for article metadata */ -function resolveContentPath(urlPath, contentDir) { - const normalized = urlPath.replace(/\/$/, ''); - const indexPath = path.join(contentDir, normalized, '_index.md'); - const directPath = path.join(contentDir, normalized + '.md'); - if (fs.existsSync(indexPath)) - return indexPath; - if (fs.existsSync(directPath)) - return directPath; - return indexPath; -} -/** - * Validate that transformed links point to existing content. - */ -function validateDocLinks(spec, contentDir) { - const errors = []; - const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g; - function extractLinks(value, jsonPath) { - if (typeof value === 'string') { - let match; - while ((match = linkPattern.exec(value)) !== null) { - const [, linkText, linkUrl] = match; - if (linkUrl.startsWith('/') && !linkUrl.startsWith('//')) { - const contentPath = resolveContentPath(linkUrl, contentDir); - if (!fs.existsSync(contentPath)) { - errors.push(`Broken link at ${jsonPath}: [${linkText}](${linkUrl})`); - } - } - } - linkPattern.lastIndex = 0; - } - else if (Array.isArray(value)) { - value.forEach((item, index) => extractLinks(item, `${jsonPath}[${index}]`)); - } - else if (value !== null && typeof value === 'object') { - for (const [key, val] of Object.entries(value)) { - extractLinks(val, `${jsonPath}.${key}`); - } - } +function generateDataFromOpenAPI(specFile, dataOutPath, articleOutPath) { + if (!fs.existsSync(dataOutPath)) { + fs.mkdirSync(dataOutPath, { recursive: true }); } - extractLinks(spec, 'spec'); - return errors; + openapiPathsToHugo.generateHugoData({ + dataOutPath, + articleOutPath, + specFile, + }); } /** - * Generate Hugo content pages from tag-based article data. + * Generate Hugo content pages from article data * * Creates markdown files with frontmatter from article metadata. - * Each article becomes a page with type: api that renders via Hugo-native - * templates. Includes operation metadata for TOC generation. + * Each article becomes a page with type: api that renders via Hugo-native templates. + * + * @param options - Generation options */ -function generateTagPagesFromArticleData(options) { - const { articlesPath, contentPath, sectionSlug, menuKey, menuParent, productDescription, skipParentMenu, specDownloadPath, articleDataKey, articleSection, } = options; +function generatePagesFromArticleData(options) { + const { articlesPath, contentPath, menuKey, menuParent, productDescription, skipParentMenu, } = options; const yaml = require('js-yaml'); const articlesFile = path.join(articlesPath, 'articles.yml'); if (!fs.existsSync(articlesFile)) { console.warn(`โš ๏ธ Articles file not found: ${articlesFile}`); return; } + // Read articles data const articlesContent = fs.readFileSync(articlesFile, 'utf8'); const data = yaml.load(articlesContent); if (!data.articles || !Array.isArray(data.articles)) { console.warn(`โš ๏ธ No articles found in ${articlesFile}`); return; } + // Ensure content directory exists if (!fs.existsSync(contentPath)) { fs.mkdirSync(contentPath, { recursive: true }); } - // Generate parent _index.md for the section - const sectionDir = path.join(contentPath, sectionSlug); - const parentIndexFile = path.join(sectionDir, '_index.md'); - if (!fs.existsSync(sectionDir)) { - fs.mkdirSync(sectionDir, { recursive: true }); + // Determine the API parent directory from the first article's path + // e.g., if article path is "api/v1/health", the API root is "api" + const firstArticlePath = data.articles[0]?.path || ''; + const apiRootDir = firstArticlePath.split('/')[0]; + // Generate parent _index.md for the API section + if (apiRootDir) { + const apiParentDir = path.join(contentPath, apiRootDir); + const parentIndexFile = path.join(apiParentDir, '_index.md'); + if (!fs.existsSync(apiParentDir)) { + fs.mkdirSync(apiParentDir, { recursive: true }); + } + if (!fs.existsSync(parentIndexFile)) { + // Build description - use product description or generate from product name + const apiDescription = productDescription || + `Use the InfluxDB HTTP API to write data, query data, and manage databases, tables, and tokens.`; + const parentFrontmatter = { + title: menuParent || 'InfluxDB HTTP API', + description: apiDescription, + weight: 104, + type: 'api', + }; + // Add menu entry for parent page (unless skipParentMenu is true) + if (menuKey && !skipParentMenu) { + parentFrontmatter.menu = { + [menuKey]: { + name: menuParent || 'InfluxDB HTTP API', + parent: 'Reference', + }, + }; + } + // Build page content with intro paragraph and children listing + const introText = apiDescription.replace('InfluxDB', '{{% product-name %}}'); + const parentContent = `--- +${yaml.dump(parentFrontmatter)}--- + +${introText} + +{{< children >}} +`; + fs.writeFileSync(parentIndexFile, parentContent); + console.log(`โœ“ Generated parent index at ${parentIndexFile}`); + } + } + // Generate a page for each article + for (const article of data.articles) { + const pagePath = path.join(contentPath, article.path); + const pageFile = path.join(pagePath, '_index.md'); + // Create directory if needed + if (!fs.existsSync(pagePath)) { + fs.mkdirSync(pagePath, { recursive: true }); + } + // Build frontmatter object + // Use menuName for display (actual endpoint path like /health) + // Fall back to name or path if menuName is not set + const displayName = article.fields.menuName || article.fields.name || article.path; + const frontmatter = { + title: displayName, + description: `API reference for ${displayName}`, + type: 'api', + // Use explicit layout to override Hugo's default section template lookup + // (Hugo's section lookup ignores `type`, so we need `layout` for the 3-column API layout) + layout: 'list', + staticFilePath: article.fields.staticFilePath, + weight: 100, + }; + // Add menu entry if menuKey is provided + // Use menuName for menu display (shows actual endpoint path like /health) + if (menuKey) { + frontmatter.menu = { + [menuKey]: { + name: displayName, + ...(menuParent && { parent: menuParent }), + }, + }; + } + // Add related links if present in article fields + if (article.fields.related && + Array.isArray(article.fields.related) && + article.fields.related.length > 0) { + frontmatter.related = article.fields.related; + } + // Add OpenAPI tags if present in article fields (for frontmatter metadata) + if (article.fields.apiTags && + Array.isArray(article.fields.apiTags) && + article.fields.apiTags.length > 0) { + frontmatter.api_tags = article.fields.apiTags; + } + const pageContent = `--- +${yaml.dump(frontmatter)}--- +`; + fs.writeFileSync(pageFile, pageContent); + } + console.log(`โœ“ Generated ${data.articles.length} content pages in ${contentPath}`); +} +/** + * Generate Hugo content pages from tag-based article data + * + * Creates markdown files with frontmatter from article metadata. + * Each article becomes a page with type: api that renders via Hugo-native templates. + * Includes operation metadata for TOC generation. + * + * @param options - Generation options + */ +function generateTagPagesFromArticleData(options) { + const { articlesPath, contentPath, menuKey, menuParent, productDescription, skipParentMenu, pathSpecFiles, } = options; + const yaml = require('js-yaml'); + const articlesFile = path.join(articlesPath, 'articles.yml'); + if (!fs.existsSync(articlesFile)) { + console.warn(`โš ๏ธ Articles file not found: ${articlesFile}`); + return; + } + // Read articles data + const articlesContent = fs.readFileSync(articlesFile, 'utf8'); + const data = yaml.load(articlesContent); + if (!data.articles || !Array.isArray(data.articles)) { + console.warn(`โš ๏ธ No articles found in ${articlesFile}`); + return; + } + // Ensure content directory exists + if (!fs.existsSync(contentPath)) { + fs.mkdirSync(contentPath, { recursive: true }); + } + // Generate parent _index.md for the API section + const apiParentDir = path.join(contentPath, 'api'); + const parentIndexFile = path.join(apiParentDir, '_index.md'); + if (!fs.existsSync(apiParentDir)) { + fs.mkdirSync(apiParentDir, { recursive: true }); } if (!fs.existsSync(parentIndexFile)) { + // Build description - use product description or generate from product name const apiDescription = productDescription || `Use the InfluxDB HTTP API to write data, query data, and manage databases, tables, and tokens.`; const parentFrontmatter = { @@ -533,18 +389,17 @@ function generateTagPagesFromArticleData(options) { description: apiDescription, weight: 104, type: 'api', - articleDataKey, - articleSection, }; + // Add menu entry for parent page (unless skipParentMenu is true) if (menuKey && !skipParentMenu) { parentFrontmatter.menu = { [menuKey]: { name: menuParent || 'InfluxDB HTTP API', - identifier: `api-reference-${articleDataKey}-${sectionSlug}`, parent: 'Reference', }, }; } + // Add alt_links for cross-product API navigation if (apiProductsMap.size > 0) { const altLinks = {}; apiProductsMap.forEach((apiPath, productName) => { @@ -552,6 +407,7 @@ function generateTagPagesFromArticleData(options) { }); parentFrontmatter.alt_links = altLinks; } + // Build page content with intro paragraph and children listing const introText = apiDescription.replace('InfluxDB', '{{% product-name %}}'); const parentContent = `--- ${yaml.dump(parentFrontmatter)}--- @@ -564,7 +420,7 @@ ${introText} console.log(`โœ“ Generated parent index at ${parentIndexFile}`); } // Generate "All endpoints" page - const allEndpointsDir = path.join(sectionDir, 'all-endpoints'); + const allEndpointsDir = path.join(apiParentDir, 'all-endpoints'); const allEndpointsFile = path.join(allEndpointsDir, '_index.md'); if (!fs.existsSync(allEndpointsDir)) { fs.mkdirSync(allEndpointsDir, { recursive: true }); @@ -576,18 +432,17 @@ ${introText} layout: 'all-endpoints', weight: 999, isAllEndpoints: true, - articleDataKey, - articleSection, }; + // Add menu entry for all-endpoints page if (menuKey) { allEndpointsFrontmatter.menu = { [menuKey]: { name: 'All endpoints', - identifier: `all-endpoints-${articleDataKey}-${sectionSlug}`, parent: menuParent || 'InfluxDB HTTP API', }, }; } + // Add alt_links for cross-product API navigation if (apiProductsMap.size > 0) { const altLinks = {}; apiProductsMap.forEach((apiPath, productName) => { @@ -606,11 +461,14 @@ All {{% product-name %}} API endpoints, sorted by path. for (const article of data.articles) { const pagePath = path.join(contentPath, article.path); const pageFile = path.join(pagePath, '_index.md'); + // Create directory if needed if (!fs.existsSync(pagePath)) { fs.mkdirSync(pagePath, { recursive: true }); } + // Build frontmatter object const title = article.fields.title || article.fields.name || article.path; const isConceptual = article.fields.isConceptual === true; + // Determine weight: use article.fields.weight if set, otherwise default to 100 const weight = article.fields.weight ?? 100; const frontmatter = { title, @@ -619,25 +477,30 @@ All {{% product-name %}} API endpoints, sorted by path. layout: isConceptual ? 'single' : 'list', staticFilePath: article.fields.staticFilePath, weight, + // Tag-based fields tag: article.fields.tag, isConceptual, menuGroup: article.fields.menuGroup, - specDownloadPath, - articleDataKey, - articleSection, }; + // Add operations for TOC generation (only for non-conceptual pages) if (!isConceptual && article.fields.operations && article.fields.operations.length > 0) { frontmatter.operations = article.fields.operations; } + // Add tag description for conceptual pages if (isConceptual && article.fields.tagDescription) { frontmatter.tagDescription = article.fields.tagDescription; } + // Add showSecuritySchemes flag for authentication pages if (article.fields.showSecuritySchemes) { frontmatter.showSecuritySchemes = true; } - // Add related links if present + // Note: We deliberately don't add menu entries for tag-based API pages. + // The API sidebar navigation (api/sidebar-nav.html) handles navigation + // for API reference pages, avoiding conflicts with existing menu items + // like "Query data" and "Write data" that exist in the main sidebar. + // Add related links if present in article fields if (article.fields.related && Array.isArray(article.fields.related) && article.fields.related.length > 0) { @@ -645,6 +508,7 @@ All {{% product-name %}} API endpoints, sorted by path. } // Add client library related link for InfluxDB 3 products if (contentPath.includes('influxdb3/') && !isConceptual) { + // Extract product segment from contentPath (e.g., "core" from ".../influxdb3/core") const influxdb3Match = contentPath.match(/influxdb3\/([^/]+)/); if (influxdb3Match) { const productSegment = influxdb3Match[1]; @@ -659,6 +523,7 @@ All {{% product-name %}} API endpoints, sorted by path. } } } + // Add alt_links for cross-product API navigation if (apiProductsMap.size > 0) { const altLinks = {}; apiProductsMap.forEach((apiPath, productName) => { @@ -672,172 +537,640 @@ ${yaml.dump(frontmatter)}--- fs.writeFileSync(pageFile, pageContent); } console.log(`โœ“ Generated ${data.articles.length} tag-based content pages in ${contentPath}`); + // NOTE: Path page generation is disabled - all operations are now displayed + // inline on tag pages using Hugo-native templates with hash-based navigation + // for deep linking. The tag pages render all operations in a single scrollable + // view with a server-side generated TOC for quick navigation. } -// --------------------------------------------------------------------------- -// Spec processing -// --------------------------------------------------------------------------- /** - * Process a single API section: transform links, write static spec, - * generate tag data, and create Hugo content pages. + * Merge article data from multiple specs into a single articles.yml + * + * Articles are merged by tag name. Operations from different specs are combined + * into the same article if they share the same tag. + * + * @param articlesFiles - Array of paths to articles.yml files to merge + * @param outputPath - Path to write the merged articles.yml */ -function processApiSection(product, api, staticBasePath) { +function mergeArticleData(articlesFiles, outputPath) { const yaml = require('js-yaml'); - const isDualApi = product.apis.length > 1; - console.log(`\n๐Ÿ“„ Processing ${api.sectionSlug} section (${api.apiKey})`); - // --- 1. Determine paths --- - // Root spec download: single โ†’ {dir}.yml, dual โ†’ {dir}-{section}.yml - const specSuffix = isDualApi ? `-${api.sectionSlug}` : ''; - const staticSpecPath = path.join(staticBasePath, `${product.staticDirName}${specSuffix}.yml`); - const staticJsonSpecPath = staticSpecPath.replace('.yml', '.json'); - // Tag specs directory - const tagSpecsBase = isDualApi - ? path.join(staticBasePath, product.staticDirName, api.sectionSlug) - : path.join(staticBasePath, product.staticDirName); - // Article data - const articlesPath = path.join(DOCS_ROOT, 'data/article_data/influxdb', product.staticDirName, api.sectionSlug); - // Download path for frontmatter - const specDownloadPath = `/openapi/${product.staticDirName}${specSuffix}.yml`; - // Path spec files for per-operation rendering - const pathSpecsDir = isDualApi - ? path.join(staticBasePath, product.staticDirName, api.sectionSlug, 'paths') - : path.join(staticBasePath, product.staticDirName, 'paths'); - // --- 2. Read and transform spec --- - if (!fs.existsSync(api.specFile)) { - console.warn(`โš ๏ธ Spec file not found: ${api.specFile}`); - return; - } - const specContent = fs.readFileSync(api.specFile, 'utf8'); - const specObject = yaml.load(specContent); - const productPath = `/${product.productDir}`; - const transformedSpec = transformDocLinks(specObject, productPath); - console.log(`โœ“ Transformed documentation links for ${api.apiKey} to ${productPath}`); - // Validate links if enabled - if (validateLinks) { - const contentDir = path.join(DOCS_ROOT, 'content'); - const linkErrors = validateDocLinks(transformedSpec, contentDir); - if (linkErrors.length > 0) { - console.warn(`\nโš ๏ธ Link validation warnings for ${api.specFile}:`); - linkErrors.forEach((err) => console.warn(` ${err}`)); + const mergedArticles = new Map(); + for (const file of articlesFiles) { + if (!fs.existsSync(file)) { + console.warn(`โš ๏ธ Articles file not found for merge: ${file}`); + continue; + } + const content = fs.readFileSync(file, 'utf8'); + const data = yaml.load(content); + if (!data.articles || !Array.isArray(data.articles)) { + console.warn(`โš ๏ธ No articles found in ${file}`); + continue; + } + for (const article of data.articles) { + const key = article.fields.tag || article.path; + const existing = mergedArticles.get(key); + if (existing) { + // Merge operations from this spec into existing article + if (article.fields.operations && article.fields.operations.length > 0) { + existing.fields.operations = [ + ...(existing.fields.operations || []), + ...article.fields.operations, + ]; + } + // Merge related links (dedup by href for both strings and objects) + if (article.fields.related && article.fields.related.length > 0) { + const existingRelated = existing.fields.related || []; + const existingHrefs = new Set(existingRelated.map((r) => (typeof r === 'string' ? r : r.href))); + const newRelated = article.fields.related.filter((r) => { + const href = typeof r === 'string' ? r : r.href; + return !existingHrefs.has(href); + }); + existing.fields.related = [...existingRelated, ...newRelated]; + } + // Keep the longest/most detailed description + if (article.fields.description && + (!existing.fields.description || + article.fields.description.length > + existing.fields.description.length)) { + existing.fields.description = article.fields.description; + } + // Merge tagDescription if not already set + if (article.fields.tagDescription && !existing.fields.tagDescription) { + existing.fields.tagDescription = article.fields.tagDescription; + } + } + else { + // Add new article + mergedArticles.set(key, JSON.parse(JSON.stringify(article))); + } } } - // --- 3. Write transformed spec to static folder --- - if (!fs.existsSync(staticBasePath)) { - fs.mkdirSync(staticBasePath, { recursive: true }); + // Convert map to array and write + const mergedData = { + articles: Array.from(mergedArticles.values()), + }; + // Ensure output directory exists + const outputDir = path.dirname(outputPath); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); } - fs.writeFileSync(staticSpecPath, yaml.dump(transformedSpec)); - console.log(`โœ“ Wrote transformed spec to ${staticSpecPath}`); - fs.writeFileSync(staticJsonSpecPath, JSON.stringify(transformedSpec, null, 2)); - console.log(`โœ“ Generated JSON spec at ${staticJsonSpecPath}`); - // --- 4. Generate tag-based data --- - console.log(`\n๐Ÿ“‹ Generating tag-based data for ${api.apiKey} in ${tagSpecsBase}...`); - openapiPathsToHugo.generateHugoDataByTag({ - specFile: staticSpecPath, - dataOutPath: tagSpecsBase, - articleOutPath: articlesPath, - includePaths: true, - }); - // Generate path-specific specs - openapiPathsToHugo.generatePathSpecificSpecs(staticSpecPath, pathSpecsDir); - // --- 5. Generate Hugo content pages --- - generateTagPagesFromArticleData({ - articlesPath, - contentPath: product.pagesDir, - sectionSlug: api.sectionSlug, - menuKey: product.menuKey, - menuParent: 'InfluxDB HTTP API', - skipParentMenu: product.skipParentMenu, - specDownloadPath, - articleDataKey: product.staticDirName, - articleSection: api.sectionSlug, - }); + // Write both YAML and JSON versions + const yamlPath = outputPath.endsWith('.yml') + ? outputPath + : `${outputPath}.yml`; + const jsonPath = yamlPath.replace(/\.yml$/, '.json'); + fs.writeFileSync(yamlPath, yaml.dump(mergedData)); + fs.writeFileSync(jsonPath, JSON.stringify(mergedData, null, 2)); + console.log(`โœ“ Merged ${mergedArticles.size} articles from ${articlesFiles.length} specs to ${outputPath}`); } /** - * Process a single product: clean outputs and process each API section. + * Product configurations for all InfluxDB editions + * + * Maps product identifiers to their OpenAPI specs and content directories */ -function processProduct(product, allStaticDirNames) { - console.log('\n' + '='.repeat(80)); - console.log(`Processing ${product.productName}`); - console.log('='.repeat(80)); - // Clean output directories before regeneration - if (!noClean && !dryRun) { - cleanProductOutputs(product, allStaticDirNames); +const productConfigs = { + // InfluxDB v2 products - use tag-based generation for consistency + // These have existing /reference/api/ pages with menu entries, + // so we skip adding menu entries to the generated parent pages. + 'cloud-v2': { + specFiles: [ + { + path: path.join(API_DOCS_ROOT, 'influxdb/cloud/influxdb-cloud-v2-openapi.yaml'), + displayName: 'API', + }, + ], + pagesDir: path.join(DOCS_ROOT, 'content/influxdb/cloud'), + description: 'InfluxDB Cloud (v2 API)', + menuKey: 'influxdb_cloud', + skipParentMenu: true, + useTagBasedGeneration: true, + }, + 'oss-v2': { + specFiles: [ + { + path: path.join(API_DOCS_ROOT, 'influxdb/v2/influxdb-oss-v2-openapi.yaml'), + displayName: 'API', + }, + ], + pagesDir: path.join(DOCS_ROOT, 'content/influxdb/v2'), + description: 'InfluxDB OSS v2', + menuKey: 'influxdb_v2', + skipParentMenu: true, + useTagBasedGeneration: true, + }, + // InfluxDB 3 products use tag-based generation for better UX + // Keys use underscores to match Hugo data directory structure + influxdb3_core: { + specFile: path.join(API_DOCS_ROOT, 'influxdb3/core/influxdb3-core-openapi.yaml'), + pagesDir: path.join(DOCS_ROOT, 'content/influxdb3/core'), + description: 'InfluxDB 3 Core', + menuKey: 'influxdb3_core', + useTagBasedGeneration: true, + }, + influxdb3_enterprise: { + specFile: path.join(API_DOCS_ROOT, 'influxdb3/enterprise/influxdb3-enterprise-openapi.yaml'), + pagesDir: path.join(DOCS_ROOT, 'content/influxdb3/enterprise'), + description: 'InfluxDB 3 Enterprise', + menuKey: 'influxdb3_enterprise', + useTagBasedGeneration: true, + }, + // Cloud Dedicated and Clustered use multiple specs: + // - Management API: database, token, and cluster management (runs on management console) + // - v2 Data API: write, query, and compatibility endpoints (runs on cluster host) + // Both specs are kept separate for downloads (different servers/auth) but article + // data is merged so the sidebar shows functional tags from both. + // These products have existing /reference/api/ pages with menu entries, + // so we skip adding menu entries to the generated parent pages. + 'cloud-dedicated': { + specFiles: [ + { + path: path.join(API_DOCS_ROOT, 'influxdb3/cloud-dedicated/management/openapi.yml'), + displayName: 'Management API', + }, + { + path: path.join(API_DOCS_ROOT, 'influxdb3/cloud-dedicated/influxdb3-cloud-dedicated-openapi.yaml'), + displayName: 'v2 Data API', + }, + ], + pagesDir: path.join(DOCS_ROOT, 'content/influxdb3/cloud-dedicated'), + description: 'InfluxDB Cloud Dedicated', + menuKey: 'influxdb3_cloud_dedicated', + skipParentMenu: true, + useTagBasedGeneration: true, + }, + 'cloud-serverless': { + specFiles: [ + { + path: path.join(API_DOCS_ROOT, 'influxdb3/cloud-serverless/influxdb3-cloud-serverless-openapi.yaml'), + displayName: 'v2 Data API', + }, + ], + pagesDir: path.join(DOCS_ROOT, 'content/influxdb3/cloud-serverless'), + description: 'InfluxDB Cloud Serverless', + menuKey: 'influxdb3_cloud_serverless', + skipParentMenu: true, + useTagBasedGeneration: true, + }, + clustered: { + specFiles: [ + { + path: path.join(API_DOCS_ROOT, 'influxdb3/clustered/management/openapi.yml'), + displayName: 'Management API', + }, + { + path: path.join(API_DOCS_ROOT, 'influxdb3/clustered/influxdb3-clustered-openapi.yaml'), + displayName: 'v2 Data API', + }, + ], + pagesDir: path.join(DOCS_ROOT, 'content/influxdb3/clustered'), + description: 'InfluxDB Clustered', + menuKey: 'influxdb3_clustered', + skipParentMenu: true, + useTagBasedGeneration: true, + }, + // InfluxDB v1 products - use tag-based generation + // These have existing /tools/api/ pages with menu entries, + // so we skip adding menu entries to the generated parent pages. + 'oss-v1': { + specFile: path.join(API_DOCS_ROOT, 'influxdb/v1/influxdb-oss-v1-openapi.yaml'), + pagesDir: path.join(DOCS_ROOT, 'content/influxdb/v1'), + description: 'InfluxDB OSS v1', + menuKey: 'influxdb_v1', + skipParentMenu: true, + useTagBasedGeneration: true, + }, + 'enterprise-v1': { + specFile: path.join(API_DOCS_ROOT, 'enterprise_influxdb/v1/influxdb-enterprise-v1-openapi.yaml'), + pagesDir: path.join(DOCS_ROOT, 'content/enterprise_influxdb/v1'), + description: 'InfluxDB Enterprise v1', + menuKey: 'enterprise_influxdb_v1', + skipParentMenu: true, + useTagBasedGeneration: true, + }, +}; +exports.productConfigs = productConfigs; +/** Fields that can contain markdown with links */ +const MARKDOWN_FIELDS = new Set(['description', 'summary']); +exports.MARKDOWN_FIELDS = MARKDOWN_FIELDS; +/** Link placeholder pattern */ +const LINK_PATTERN = /\/influxdb\/version\//g; +exports.LINK_PATTERN = LINK_PATTERN; +/** Absolute docs site URLs โ†’ relative paths for Hugo rendering */ +const DOCS_HOST_PATTERN = /https?:\/\/docs\.influxdata\.com(\/[^\s)'"]*)/g; +/** Base URL for absolutifying links in downloadable specs */ +const DOCS_BASE_URL = 'https://docs.influxdata.com'; +/** + * Derive documentation root from spec file path. + * + * @example + * 'api-docs/influxdb3/core/influxdb3-core-openapi.yaml' โ†’ '/influxdb3/core' + * 'api-docs/influxdb3/enterprise/influxdb3-enterprise-openapi.yaml' โ†’ '/influxdb3/enterprise' + * 'api-docs/influxdb/v2/influxdb-oss-v2-openapi.yaml' โ†’ '/influxdb/v2' + * 'api-docs/influxdb/v1/influxdb-oss-v1-openapi.yaml' โ†’ '/influxdb/v1' + * 'api-docs/enterprise_influxdb/v1/influxdb-enterprise-v1-openapi.yaml' โ†’ '/enterprise_influxdb/v1' + */ +function deriveProductPath(specPath) { + // Match: api-docs/[_build/](enterprise_influxdb|influxdb3|influxdb)/(product-or-version)/... + const match = specPath.match(/api-docs\/(?:_build\/)?(enterprise_influxdb|influxdb3?)\/([\w-]+)\//); + if (!match) { + throw new Error(`Cannot derive product path from: ${specPath}`); } - const staticBasePath = path.join(DOCS_ROOT, 'static/openapi'); - // Fetch specs if needed - if (!skipFetch) { - const getswaggerScript = path.join(API_DOCS_ROOT, 'getswagger.sh'); - if (fs.existsSync(getswaggerScript)) { - // The build function in generate-api-docs.sh handles per-product - // fetching. When called standalone, use product directory name. - execCommand(`cd ${API_DOCS_ROOT} && ./getswagger.sh ${product.productDir} -B`, `Fetching OpenAPI spec for ${product.productName}`); + return `/${match[1]}/${match[2]}`; +} +/** + * Transform documentation links in OpenAPI spec markdown fields. + * + * 1. Replaces `/influxdb/version/` placeholder with the actual product path. + * 2. Strips `https://docs.influxdata.com` host from absolute internal URLs, + * converting them to relative paths for Hugo rendering. + * + * Only processes `description` and `summary` fields (MARKDOWN_FIELDS). + * Non-markdown fields like `servers[].url` are preserved as-is. + * + * @param spec - Parsed OpenAPI spec object + * @param productPath - Target path (e.g., '/influxdb3/core') + * @returns Spec with transformed links (new object, original unchanged) + */ +function transformDocLinks(spec, productPath) { + function transformString(value) { + return value + .replace(LINK_PATTERN, `${productPath}/`) + .replace(DOCS_HOST_PATTERN, '$1'); + } + function transformValue(value) { + if (typeof value === 'string') { + return transformString(value); } - else { - console.log(`โš ๏ธ getswagger.sh not found, skipping fetch step`); + if (Array.isArray(value)) { + return value.map(transformValue); } + if (value !== null && typeof value === 'object') { + return transformObject(value); + } + return value; + } + function transformObject(obj) { + const result = {}; + for (const [key, value] of Object.entries(obj)) { + if (MARKDOWN_FIELDS.has(key) && typeof value === 'string') { + result[key] = transformString(value); + } + else if (value !== null && typeof value === 'object') { + result[key] = transformValue(value); + } + else { + result[key] = value; + } + } + return result; + } + return transformObject(spec); +} +/** + * Prepend base URL to relative doc links for downloadable specs. + * Transforms markdown link targets (`](/path)`) and `x-related` href values. + * Skips external URLs, anchors, and protocol-relative URLs. + * + * @param spec - Parsed OpenAPI spec object with relative links + * @param baseUrl - Base URL to prepend (e.g., 'https://docs.influxdata.com') + * @returns Spec with absolute links (new object, original unchanged) + */ +function absolutifyLinks(spec, baseUrl) { + // Match `](/path` but not `](//` (protocol-relative) + const INTERNAL_LINK_RE = /(]\()(\/(?!\/))/g; + function transformValue(value, key, parent) { + if (typeof value === 'string') { + if (key && MARKDOWN_FIELDS.has(key)) { + return value.replace(INTERNAL_LINK_RE, `$1${baseUrl}$2`); + } + if (key === 'href' && + parent?.title && + value.startsWith('/')) { + return `${baseUrl}${value}`; + } + // externalDocs.url โ€” standard OpenAPI field + if (key === 'url' && + parent?.description && + value.startsWith('/')) { + return `${baseUrl}${value}`; + } + return value; + } + if (Array.isArray(value)) { + return value.map((item) => transformValue(item)); + } + if (value !== null && typeof value === 'object') { + return transformObject(value); + } + return value; + } + function transformObject(obj) { + const result = {}; + for (const [k, v] of Object.entries(obj)) { + result[k] = transformValue(v, k, obj); + } + return result; + } + return transformObject(spec); +} +/** + * Resolve a URL path to a content file path. + * + * @example + * '/influxdb3/core/api/auth/' โ†’ 'content/influxdb3/core/api/auth/_index.md' + */ +function resolveContentPath(urlPath, contentDir) { + const normalized = urlPath.replace(/\/$/, ''); + const indexPath = path.join(contentDir, normalized, '_index.md'); + const directPath = path.join(contentDir, normalized + '.md'); + if (fs.existsSync(indexPath)) { + return indexPath; + } + if (fs.existsSync(directPath)) { + return directPath; + } + return indexPath; // Return expected path for error message +} +/** + * Validate that transformed links point to existing content. + * + * @param spec - Transformed OpenAPI spec + * @param contentDir - Path to Hugo content directory + * @returns Array of error messages for broken links + */ +function validateDocLinks(spec, contentDir) { + const errors = []; + const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g; + function extractLinks(value, jsonPath) { + if (typeof value === 'string') { + let match; + while ((match = linkPattern.exec(value)) !== null) { + const [, linkText, linkUrl] = match; + // Only validate internal links (start with /) + if (linkUrl.startsWith('/') && !linkUrl.startsWith('//')) { + const contentPath = resolveContentPath(linkUrl, contentDir); + if (!fs.existsSync(contentPath)) { + errors.push(`Broken link at ${jsonPath}: [${linkText}](${linkUrl})`); + } + } + } + // Reset regex lastIndex for next string + linkPattern.lastIndex = 0; + } + else if (Array.isArray(value)) { + value.forEach((item, index) => extractLinks(item, `${jsonPath}[${index}]`)); + } + else if (value !== null && typeof value === 'object') { + for (const [key, val] of Object.entries(value)) { + extractLinks(val, `${jsonPath}.${key}`); + } + } + } + extractLinks(spec, 'spec'); + return errors; +} +/** + * Convert display name to filename-safe slug + * + * @param displayName - Display name (e.g., "Management API") + * @returns Filename-safe slug (e.g., "management-api") + */ +function slugifyDisplayName(displayName) { + return displayName + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-|-$/g, ''); +} +/** + * Process a single spec file: transform links, write to static folder + * + * @param specConfig - Spec file configuration + * @param staticPath - Static directory path + * @param staticDirName - Product directory name + * @param productKey - Product identifier + * @returns Object with paths to generated files, or null if processing failed + */ +function processSpecFile(specConfig, staticPath, staticDirName, productKey) { + const yaml = require('js-yaml'); + if (!fs.existsSync(specConfig.path)) { + console.warn(`โš ๏ธ Spec file not found: ${specConfig.path}`); + return null; + } + // Generate filename from display name or use default. + // Strip staticDirName prefix from the spec filename to avoid doubled names + // (e.g., influxdb3-core + influxdb3-core-openapi โ†’ influxdb3-core-openapi). + let specSlug; + if (specConfig.displayName) { + specSlug = slugifyDisplayName(specConfig.displayName); } else { - console.log(`โญ๏ธ Skipping getswagger.sh (--skip-fetch flag set)`); + const rawName = path.parse(specConfig.path).name; + const prefix = `${staticDirName}-`; + specSlug = rawName.startsWith(prefix) + ? rawName.slice(prefix.length) + : rawName; } - // Process each API section independently - for (const api of product.apis) { - processApiSection(product, api, staticBasePath); + const staticSpecPath = path.join(staticPath, `${staticDirName}-${specSlug}.yml`); + const staticJsonSpecPath = path.join(staticPath, `${staticDirName}-${specSlug}.json`); + const articlesPath = path.join(DOCS_ROOT, `data/article_data/influxdb/${productKey}/${specSlug}`); + try { + const specContent = fs.readFileSync(specConfig.path, 'utf8'); + const specObject = yaml.load(specContent); + // Transform documentation links (/influxdb/version/ -> actual product path) + const productPath = deriveProductPath(specConfig.path); + const transformedSpec = transformDocLinks(specObject, productPath); + console.log(`โœ“ Transformed documentation links for ${specConfig.displayName || specSlug} to ${productPath}`); + // Validate links if enabled + if (validateLinks) { + const contentDir = path.resolve(__dirname, '../../content'); + const linkErrors = validateDocLinks(transformedSpec, contentDir); + if (linkErrors.length > 0) { + console.warn(`\nโš ๏ธ Link validation warnings for ${specConfig.path}:`); + linkErrors.forEach((err) => console.warn(` ${err}`)); + } + } + // Write Hugo spec (relative links) for article generation and templates + const hugoSpecPath = staticSpecPath.replace(/\.yml$/, '-hugo.yml'); + fs.writeFileSync(hugoSpecPath, yaml.dump(transformedSpec)); + // Absolutify links for downloadable specs (relative paths โ†’ full URLs) + const downloadSpec = absolutifyLinks(transformedSpec, DOCS_BASE_URL); + // Write downloadable spec to static folder + fs.writeFileSync(staticSpecPath, yaml.dump(downloadSpec)); + console.log(`โœ“ Wrote downloadable spec to ${staticSpecPath}`); + fs.writeFileSync(staticJsonSpecPath, JSON.stringify(downloadSpec, null, 2)); + console.log(`โœ“ Generated JSON spec at ${staticJsonSpecPath}`); + return { staticSpecPath, staticJsonSpecPath, hugoSpecPath, articlesPath }; + } + catch (specError) { + console.warn(`โš ๏ธ Could not process spec: ${specError}`); + return null; } - console.log(`\nโœ… Successfully processed ${product.productName}\n`); } -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- -function main() { - const args = process.argv.slice(2).filter((arg) => !arg.startsWith('--')); - // Discover all products from .config.yml files - const allProducts = discoverProducts(); - if (allProducts.length === 0) { - console.error('โŒ No products discovered. Ensure .config.yml files exist under api-docs/.'); +/** + * Process a single product: fetch spec, generate data, and create pages + * + * Supports both single spec (specFile) and multiple specs (specFiles). + * For multiple specs, article data is merged so the sidebar shows + * functional tags from all specs. + * + * @param productKey - Product identifier (e.g., 'cloud-v2') + * @param config - Product configuration + */ +function processProduct(productKey, config) { + console.log('\n' + '='.repeat(80)); + console.log(`Processing ${config.description || productKey}`); + console.log('='.repeat(80)); + // Clean output directories before regeneration (unless --no-clean, --dry-run, or --static-only) + if (!noClean && !dryRun && !staticOnly) { + cleanProductOutputs(productKey, config); + } + const staticPath = path.join(DOCS_ROOT, 'static/openapi'); + const staticDirName = getStaticDirName(productKey); + const staticPathsPath = path.join(staticPath, `${staticDirName}/paths`); + const mergedArticlesPath = path.join(DOCS_ROOT, `data/article_data/influxdb/${productKey}`); + // Ensure static directory exists + if (!fs.existsSync(staticPath)) { + fs.mkdirSync(staticPath, { recursive: true }); + } + try { + // Determine spec files to process + const specFiles = config.specFiles + ? config.specFiles + : config.specFile + ? [{ path: config.specFile }] + : []; + if (specFiles.length === 0) { + console.warn(`โš ๏ธ No spec files configured for ${productKey}`); + return; + } + // Check if any spec files exist + const existingSpecs = specFiles.filter((s) => fs.existsSync(s.path)); + if (existingSpecs.length === 0) { + console.warn(`โš ๏ธ No spec files found for ${productKey}. Run getswagger.sh first if needed.`); + return; + } + // Process each spec file + const processedSpecs = []; + const allPathSpecFiles = new Map(); + for (const specConfig of specFiles) { + console.log(`\n๐Ÿ“„ Processing spec: ${specConfig.displayName || specConfig.path}`); + const result = processSpecFile(specConfig, staticPath, staticDirName, productKey); + if (result) { + processedSpecs.push(result); + // Generate tag-based article data for this spec (skip in --static-only mode) + if (!staticOnly && config.useTagBasedGeneration) { + const specSlug = specConfig.displayName + ? slugifyDisplayName(specConfig.displayName) + : path.parse(specConfig.path).name; + const staticTagsPath = path.join(staticPath, `${staticDirName}/${specSlug}`); + console.log(`\n๐Ÿ“‹ Generating tag-based data for ${specConfig.displayName || specSlug}...`); + openapiPathsToHugo.generateHugoDataByTag({ + specFile: result.hugoSpecPath, + dataOutPath: staticTagsPath, + articleOutPath: result.articlesPath, + includePaths: true, + }); + // Generate path-specific specs (use Hugo spec with relative links) + const specPathsPath = path.join(staticPathsPath, specSlug); + const pathSpecFiles = openapiPathsToHugo.generatePathSpecificSpecs(result.hugoSpecPath, specPathsPath); + // Merge path spec files into combined map + pathSpecFiles.forEach((value, key) => { + allPathSpecFiles.set(key, value); + }); + } + } + } + // Article generation (skip in --static-only mode) + if (!staticOnly) { + // Merge article data from all specs (for multi-spec products) + if (processedSpecs.length > 1) { + console.log(`\n๐Ÿ“‹ Merging article data from ${processedSpecs.length} specs...`); + const articlesFiles = processedSpecs.map((s) => path.join(s.articlesPath, 'articles.yml')); + mergeArticleData(articlesFiles, path.join(mergedArticlesPath, 'articles.yml')); + } + else if (processedSpecs.length === 1) { + // Single spec - copy articles to final location if needed + const sourceArticles = path.join(processedSpecs[0].articlesPath, 'articles.yml'); + const targetArticles = path.join(mergedArticlesPath, 'articles.yml'); + // Only copy if source and target are different + if (sourceArticles !== targetArticles && + fs.existsSync(sourceArticles)) { + if (!fs.existsSync(mergedArticlesPath)) { + fs.mkdirSync(mergedArticlesPath, { recursive: true }); + } + fs.copyFileSync(sourceArticles, targetArticles); + fs.copyFileSync(sourceArticles.replace('.yml', '.json'), targetArticles.replace('.yml', '.json')); + console.log(`โœ“ Copied article data to ${mergedArticlesPath}`); + } + } + // Generate Hugo content pages from (merged) article data + if (config.useTagBasedGeneration) { + generateTagPagesFromArticleData({ + articlesPath: mergedArticlesPath, + contentPath: config.pagesDir, + menuKey: config.menuKey, + menuParent: 'InfluxDB HTTP API', + skipParentMenu: config.skipParentMenu, + pathSpecFiles: allPathSpecFiles, + }); + } + else { + generatePagesFromArticleData({ + articlesPath: mergedArticlesPath, + contentPath: config.pagesDir, + menuKey: config.menuKey, + menuParent: 'InfluxDB HTTP API', + skipParentMenu: config.skipParentMenu, + }); + } + } + console.log(`\nโœ… Successfully processed ${config.description || productKey}\n`); + } + catch (error) { + console.error(`\nโŒ Error processing ${productKey}:`, error); process.exit(1); } +} +/** + * Main execution function + */ +function main() { + // Filter out CLI flags from arguments + const args = process.argv.slice(2).filter((arg) => !arg.startsWith('--')); // Determine which products to process let productsToProcess; if (args.length === 0) { - productsToProcess = allProducts; - console.log(`\n๐Ÿ“‹ Discovered ${allProducts.length} products, processing all...\n`); + // No arguments: process all products + productsToProcess = Object.keys(productConfigs); + console.log('\n๐Ÿ“‹ Processing all products...\n'); } else { - // Match by staticDirName or productDir - productsToProcess = []; - const invalid = []; - for (const arg of args) { - const found = allProducts.find((p) => p.staticDirName === arg || - p.productDir === arg || - p.productDir.replace(/\//g, '-') === arg); - if (found) { - productsToProcess.push(found); - } - else { - invalid.push(arg); - } - } - if (invalid.length > 0) { - console.error(`\nโŒ Unknown product identifier(s): ${invalid.join(', ')}`); - console.error('\nDiscovered products:'); - allProducts.forEach((p) => { - console.error(` - ${p.staticDirName} (${p.productName}) [${p.productDir}]`); - }); - process.exit(1); - } - console.log(`\n๐Ÿ“‹ Processing specified products: ${productsToProcess.map((p) => p.staticDirName).join(', ')}\n`); + // Arguments provided: process only specified products + productsToProcess = args; + console.log(`\n๐Ÿ“‹ Processing specified products: ${productsToProcess.join(', ')}\n`); + } + // Validate product keys + const invalidProducts = productsToProcess.filter((key) => !productConfigs[key]); + if (invalidProducts.length > 0) { + console.error(`\nโŒ Invalid product identifier(s): ${invalidProducts.join(', ')}`); + console.error('\nValid products:'); + Object.keys(productConfigs).forEach((key) => { + console.error(` - ${key}: ${productConfigs[key].description}`); + }); + process.exit(1); } - // Collect all staticDirNames for prefix-safe cleanup - const allStaticDirNames = allProducts.map((p) => p.staticDirName); // Handle dry-run mode if (dryRun) { console.log('\n๐Ÿ“‹ DRY RUN MODE - No files will be modified\n'); - productsToProcess.forEach((p) => showDryRunPreview(p, allStaticDirNames)); + productsToProcess.forEach((productKey) => { + showDryRunPreview(productKey, productConfigs[productKey]); + }); console.log('\nDry run complete. No files were modified.'); return; } // Process each product - productsToProcess.forEach((product) => { - processProduct(product, allStaticDirNames); + productsToProcess.forEach((productKey) => { + const config = productConfigs[productKey]; + processProduct(productKey, config); }); console.log('\n' + '='.repeat(80)); console.log('โœ… All products processed successfully!'); diff --git a/api-docs/scripts/dist/openapi-paths-to-hugo-data/index.js b/api-docs/scripts/dist/openapi-paths-to-hugo-data/index.js index 4874d1000..de9134bf6 100644 --- a/api-docs/scripts/dist/openapi-paths-to-hugo-data/index.js +++ b/api-docs/scripts/dist/openapi-paths-to-hugo-data/index.js @@ -731,9 +731,12 @@ function createArticleDataForTag(openapi, operations, tagMeta) { if (tagMeta?.['x-influxdatadocs-related']) { tagMeta['x-influxdatadocs-related'].forEach(addRelated); } - // Tag-level externalDocs (legacy single link) + // Tag-level externalDocs (standard OpenAPI field โ€” single link) if (tagMeta?.externalDocs?.url) { - addRelated(tagMeta.externalDocs.url); + addRelated({ + title: tagMeta.externalDocs.description || tagMeta.externalDocs.url, + href: tagMeta.externalDocs.url, + }); } // Operation-level related links operations.forEach((op) => { @@ -744,7 +747,10 @@ function createArticleDataForTag(openapi, operations, tagMeta) { op.related.forEach(addRelated); } if (op.externalDocs?.url) { - addRelated(op.externalDocs.url); + addRelated({ + title: op.externalDocs.description || op.externalDocs.url, + href: op.externalDocs.url, + }); } }); if (relatedItems.length > 0) { diff --git a/api-docs/scripts/generate-openapi-articles.ts b/api-docs/scripts/generate-openapi-articles.ts index b6ac0f972..ea55e4471 100644 --- a/api-docs/scripts/generate-openapi-articles.ts +++ b/api-docs/scripts/generate-openapi-articles.ts @@ -1054,6 +1054,9 @@ const MARKDOWN_FIELDS = new Set(['description', 'summary']); /** Link placeholder pattern */ const LINK_PATTERN = /\/influxdb\/version\//g; +/** Absolute docs site URLs โ†’ relative paths for Hugo rendering */ +const DOCS_HOST_PATTERN = /https?:\/\/docs\.influxdata\.com(\/[^\s)'"]*)/g; + /** Base URL for absolutifying links in downloadable specs */ const DOCS_BASE_URL = 'https://docs.influxdata.com'; @@ -1080,7 +1083,13 @@ function deriveProductPath(specPath: string): string { /** * Transform documentation links in OpenAPI spec markdown fields. - * Replaces `/influxdb/version/` with the actual product path. + * + * 1. Replaces `/influxdb/version/` placeholder with the actual product path. + * 2. Strips `https://docs.influxdata.com` host from absolute internal URLs, + * converting them to relative paths for Hugo rendering. + * + * Only processes `description` and `summary` fields (MARKDOWN_FIELDS). + * Non-markdown fields like `servers[].url` are preserved as-is. * * @param spec - Parsed OpenAPI spec object * @param productPath - Target path (e.g., '/influxdb3/core') @@ -1090,9 +1099,15 @@ function transformDocLinks( spec: Record, productPath: string ): Record { + function transformString(value: string): string { + return value + .replace(LINK_PATTERN, `${productPath}/`) + .replace(DOCS_HOST_PATTERN, '$1'); + } + function transformValue(value: unknown): unknown { if (typeof value === 'string') { - return value.replace(LINK_PATTERN, `${productPath}/`); + return transformString(value); } if (Array.isArray(value)) { return value.map(transformValue); @@ -1109,7 +1124,7 @@ function transformDocLinks( const result: Record = {}; for (const [key, value] of Object.entries(obj)) { if (MARKDOWN_FIELDS.has(key) && typeof value === 'string') { - result[key] = value.replace(LINK_PATTERN, `${productPath}/`); + result[key] = transformString(value); } else if (value !== null && typeof value === 'object') { result[key] = transformValue(value); } else { @@ -1154,6 +1169,14 @@ function absolutifyLinks( ) { return `${baseUrl}${value}`; } + // externalDocs.url โ€” standard OpenAPI field + if ( + key === 'url' && + parent?.description && + value.startsWith('/') + ) { + return `${baseUrl}${value}`; + } return value; } if (Array.isArray(value)) { @@ -1276,6 +1299,7 @@ function processSpecFile( ): { staticSpecPath: string; staticJsonSpecPath: string; + hugoSpecPath: string; articlesPath: string; } | null { const yaml = require('js-yaml'); @@ -1333,6 +1357,10 @@ function processSpecFile( } } + // Write Hugo spec (relative links) for article generation and templates + const hugoSpecPath = staticSpecPath.replace(/\.yml$/, '-hugo.yml'); + fs.writeFileSync(hugoSpecPath, yaml.dump(transformedSpec)); + // Absolutify links for downloadable specs (relative paths โ†’ full URLs) const downloadSpec = absolutifyLinks(transformedSpec, DOCS_BASE_URL); @@ -1346,7 +1374,7 @@ function processSpecFile( ); console.log(`โœ“ Generated JSON spec at ${staticJsonSpecPath}`); - return { staticSpecPath, staticJsonSpecPath, articlesPath }; + return { staticSpecPath, staticJsonSpecPath, hugoSpecPath, articlesPath }; } catch (specError) { console.warn(`โš ๏ธ Could not process spec: ${specError}`); return null; @@ -1444,16 +1472,16 @@ function processProduct(productKey: string, config: ProductConfig): void { `\n๐Ÿ“‹ Generating tag-based data for ${specConfig.displayName || specSlug}...` ); openapiPathsToHugo.generateHugoDataByTag({ - specFile: result.staticSpecPath, + specFile: result.hugoSpecPath, dataOutPath: staticTagsPath, articleOutPath: result.articlesPath, includePaths: true, }); - // Generate path-specific specs + // Generate path-specific specs (use Hugo spec with relative links) const specPathsPath = path.join(staticPathsPath, specSlug); const pathSpecFiles = openapiPathsToHugo.generatePathSpecificSpecs( - result.staticSpecPath, + result.hugoSpecPath, specPathsPath ); diff --git a/api-docs/scripts/openapi-paths-to-hugo-data/index.ts b/api-docs/scripts/openapi-paths-to-hugo-data/index.ts index 185b1e508..cd635eeb9 100644 --- a/api-docs/scripts/openapi-paths-to-hugo-data/index.ts +++ b/api-docs/scripts/openapi-paths-to-hugo-data/index.ts @@ -1159,9 +1159,12 @@ function createArticleDataForTag( (tagMeta['x-influxdatadocs-related'] as string[]).forEach(addRelated); } - // Tag-level externalDocs (legacy single link) + // Tag-level externalDocs (standard OpenAPI field โ€” single link) if (tagMeta?.externalDocs?.url) { - addRelated(tagMeta.externalDocs.url); + addRelated({ + title: tagMeta.externalDocs.description || tagMeta.externalDocs.url, + href: tagMeta.externalDocs.url, + }); } // Operation-level related links @@ -1173,7 +1176,10 @@ function createArticleDataForTag( op.related.forEach(addRelated); } if (op.externalDocs?.url) { - addRelated(op.externalDocs.url); + addRelated({ + title: op.externalDocs.description || op.externalDocs.url, + href: op.externalDocs.url, + }); } });