API Documentation Generator
Run ID: 69cc95bb3e7fb09ff16a33dd2026-04-01Development
PantheraHive BOS
BOS Dashboard

API Documentation Generator: Architectural Plan

This document outlines the comprehensive architectural plan for the "API Documentation Generator," a system designed to automate the creation of professional, detailed, and user-friendly API documentation. This plan covers core components, key features, technology recommendations, and a development roadmap.

1. Project Overview

The API Documentation Generator aims to streamline the process of producing high-quality API documentation by taking API specifications as input and generating rich, interactive, and customizable output. The documentation will include endpoint details, request/response examples, authentication guides, and SDK usage examples, catering to both developers and technical writers.

2. Architectural Goals

The primary architectural goals for this generator are:

3. Core Architectural Components

The generator will be structured into several logical layers, each with specific responsibilities:

3.1. Input Processing Layer

This layer is responsible for ingesting and validating API specifications from various sources.

* File System: Local YAML/JSON files (e.g., openapi.yaml).

* URL: Remote API specification URLs.

* Version Control Systems (VCS): Integration with Git repositories (e.g., GitHub, GitLab) to pull specs.

* OpenAPI/Swagger Parser: Support for OpenAPI Specification (OAS) versions 2.0 and 3.x.

(Future consideration: RAML, API Blueprint, Postman Collections parsers).*

3.2. Internal Data Model Layer

This layer defines a standardized, format-agnostic representation of the API specification, allowing the rest of the system to work with a unified data structure regardless of the input source.

3.3. Content Generation Layer

This layer uses the internal data model to generate the raw content for various documentation sections. This is where the "intelligence" of documentation creation resides.

* HTTP method, path, summary, description.

* Request parameters (path, query, header, cookie) with types, descriptions, and examples.

* Request body schemas and examples (JSON, XML, form data).

* Response codes, schemas, and examples for success and error scenarios.

* API Key authentication.

* OAuth 2.0 flows (Authorization Code, Client Credentials, Implicit, Password).

* HTTP Basic/Bearer authentication.

* Examples of how to include authentication in requests.

* Language-Specific Code Snippet Engine: Generates code examples for common programming languages (e.g., Python, JavaScript, cURL, Java, Go) demonstrating:

* How to make API calls to specific endpoints.

* How to handle request/response bodies.

* How to pass authentication tokens.

* Parameter usage.

Conceptual SDK Integration: Provides guidance on how an SDK would* abstract these calls, even if a full SDK isn't generated.

* Introduction & Getting Started: Generates boilerplate content based on API metadata.

* Error Handling Guide: Summarizes common error responses defined in the spec.

* Glossary/Definitions: Lists reusable schemas/components.

* Custom Content Injector: Allows users to include their own Markdown or HTML content at specific points.

3.4. Templating & Rendering Layer

This layer takes the generated content and applies templates to produce the final human-readable documentation in various formats.

* HTML Renderer: Generates static HTML files, potentially with client-side interactivity (e.g., collapsible sections, search, "Try It Out" consoles).

* Markdown Renderer: Generates Markdown files suitable for platforms like GitHub Wikis, Confluence, or further processing by static site generators (e.g., MkDocs).

(Future consideration: PDF Renderer, ReStructuredText Renderer).*

3.5. Output & Deployment Layer

This layer handles the delivery of the generated documentation.

* CI/CD Hooks: Integration points for automated documentation generation and deployment as part of a CI/CD pipeline.

* Hosting Service Adapters: Options to publish directly to services like Netlify, Vercel, or S3.

3.6. User Interface / CLI Layer

This layer provides the interface for users to interact with the generator.

* generate <spec_path> --output <dir> --format <html|md> --config <config_file>

* Options for theme selection, custom templates, specific content inclusion/exclusion.

4. Key Features & Functionality

5. Technology Stack Recommendations

Based on the architectural goals and features, here's a recommended technology stack:

* Rationale: Rich ecosystem for text processing, data manipulation, and web development. Excellent libraries for YAML/JSON parsing, templating, and static site generation.

* PyYAML / json: For parsing YAML/JSON API specifications.

* openapi-spec-validator: For validating OpenAPI specifications.

* prance / flex: Libraries for resolving OpenAPI references and processing specs.

* requests (for "Try It Out"): If an interactive console is implemented.

* httpx: For async capabilities if needed.

* Jinja2: Powerful and flexible templating engine for generating HTML, Markdown, or other text formats.

* Pygments: For syntax highlighting of code examples.

* HTML: Standard output, potentially enhanced with client-side JavaScript (e.g., Vue.js, React, or vanilla JS) for interactivity, search, and "Try It Out" functionality.

* Markdown: For integration with other documentation systems.

* Click / Typer: Robust and easy-to-use frameworks for building command-line interfaces.

MkDocs / Sphinx: The generator can output Markdown/reStructuredText that can then be processed by these tools for advanced static site features. This offers a hybrid approach where our generator focuses on content creation and these tools handle site rendering*.

* curlify (Python): To generate cURL commands from requests objects.

* Custom code generation logic: For Python, JavaScript, Java, Go examples, tailored to common HTTP client libraries in those languages.

6. Data Flow Diagram (Conceptual)

mermaid • 556 chars
graph TD
    A[API Specification Source] --> B(Input Source Adapter)
    B --> C(Specification Parser)
    C --> D(Schema Validator)
    D -- Validated Spec --> E[Internal Data Model (AST/IR)]

    E -- Data Model --> F[Content Generation Layer]
    F -- Raw Content --> G[Templating Engine]
    G -- Templates + Themes --> H[Output Format Renderers]
    H --> I[Output & Deployment Layer]

    I -- Generated Docs --> J[Static Files]
    I -- Deployment --> K[Hosting/CI/CD]

    L[User (CLI/GUI)] --> A
    L --> M[Configuration]
    M --> F
    M --> G
Sandboxed live preview

7. Scalability & Maintainability Considerations

  • Modularity: The layered architecture ensures that changes in one component (e.g., adding a new input format) do not drastically impact others (e.g., the rendering engine).
  • Configuration-driven: Most aspects of generation and styling should be configurable via external files, minimizing code changes for customization.
  • Testing: Comprehensive unit tests for parsers, data model, and content generators. Integration tests for end-to-end generation.
  • Documentation: The generator itself should be well-documented for developers contributing to it.
  • Performance: For very large API specifications, consider lazy loading or incremental processing if the entire spec consumes too much memory.

8. Development Roadmap & Learning Path

This section outlines the phased development schedule, key learning objectives for the development team, recommended resources, major milestones, and assessment strategies.

8.1. Phased Development Schedule (Agile Sprints)

  • Phase 1: Foundation (Weeks 1-4)

* Focus: Core parsing, internal data model, basic HTML rendering.

* Sprint 1 (Week 1-2):

* Implement OpenAPI 3.x YAML/JSON parsing.

* Create initial internal data model for paths, operations, parameters, and schemas.

* Develop CLI for basic input/output.

* Sprint 2 (Week 3-4):

* Implement basic HTML templating with Jinja2.

* Generate simple endpoint lists with summaries.

* Add basic CSS styling.

  • Phase 2: Core Content & Interactivity (Weeks 5-8)

* Focus: Detailed content generation, request/response examples, authentication.

* Sprint 3 (Week 5-6):

* Enhance endpoint details: full descriptions, parameter tables, request body schemas.

* Generate request/response examples based on OpenAPI schemas.

* Implement syntax highlighting for code blocks.

* Sprint 4 (Week 7-8):

* Develop authentication guide generation (API Key, OAuth 2.0).

* Implement client-side search functionality (for HTML output).

* Introduce basic theme customization options.

  • Phase 3: Advanced Features & SDK Examples (Weeks 9-12)

* Focus: SDK usage examples, custom content, output formats.

gemini Output

This deliverable provides the core code for an API Documentation Generator. As part of the "API Documentation Generator" workflow, this step focuses on generating the foundational Python script that can parse an OpenAPI/Swagger specification and render its contents into a human-readable Markdown format.

This script demonstrates how to extract crucial API details such as endpoint descriptions, parameters, request/response examples, and authentication methods, then structure them into a professional documentation format.


API Documentation Generator: Core Code

This section provides a Python script (api_doc_generator.py) designed to parse an OpenAPI 3.0 specification (YAML or JSON) and generate detailed API documentation in Markdown format.

Purpose

The generated code aims to fulfill the requirements of producing professional API documentation by:

  1. Parsing OpenAPI Specification: Ingesting a standard API definition.
  2. Extracting Endpoint Details: Identifying paths, HTTP methods, summaries, descriptions, and associated tags.
  3. Detailing Parameters: Describing path, query, header, and cookie parameters, including their types, descriptions, and optionality.
  4. Presenting Request Bodies: Showing request body schemas and example payloads for various content types.
  5. Documenting Responses: Outlining possible response codes, their descriptions, schema definitions, and example payloads.
  6. Explaining Authentication: Generating a guide based on the defined security schemes.
  7. Conceptual SDK Usage: Providing a placeholder for where SDK usage examples would typically reside.

How it Works (Conceptual Overview)

The script follows these general steps:

  1. Load Specification: Reads an OpenAPI YAML or JSON file.
  2. Resolve References ($ref): Recursively resolves internal and external references within the specification to get the full schema definitions.
  3. Process Global Information: Extracts API title, version, description, and server URLs.
  4. Generate Authentication Section: Iterates through securitySchemes to describe how to authenticate with the API.
  5. Iterate Endpoints: Loops through each path and HTTP method defined in the paths section.
  6. Generate Endpoint Documentation: For each endpoint, it constructs a detailed Markdown section including:

* Summary and Description

* HTTP Method and Path

* Parameters

* Request Body (if applicable)

* Responses (for various status codes)

  1. Output: Combines all generated sections into a single Markdown string, which is then saved to a file.

Production-Ready Code: api_doc_generator.py

This Python script is designed to be clean, well-commented, and structured for clarity and maintainability.


import yaml
import json
import os
import re

# --- Helper Functions ---

def resolve_ref(ref_path, spec_data, visited_refs=None):
    """
    Recursively resolves an OpenAPI $ref path within the spec_data.
    Handles circular references by returning the ref path if already visited.
    """
    if visited_refs is None:
        visited_refs = set()

    if ref_path in visited_refs:
        print(f"Warning: Circular reference detected for {ref_path}. Returning ref path.")
        return {"$ref": ref_path} # Return the ref path to prevent infinite loop

    visited_refs.add(ref_path)

    parts = ref_path.split('/')
    if parts[0] == '#':
        current = spec_data
        for part in parts[1:]:
            part = part.replace('~1', '/').replace('~0', '~') # Handle JSON Pointer escaping
            if part in current:
                current = current[part]
            else:
                print(f"Error: Could not resolve part '{part}' in ref '{ref_path}'")
                return None
        return current
    else:
        # For external references, you'd need to load the external file.
        # This simplified version only handles internal references.
        print(f"Warning: External reference '{ref_path}' not supported by this resolver.")
        return {"$ref": ref_path}


def get_schema_details(schema, spec_data, components, indent=0, visited_schemas=None):
    """
    Recursively generates a description for a given schema.
    Handles $ref resolution and basic schema types.
    """
    if visited_schemas is None:
        visited_schemas = set()

    schema_str = []
    prefix = "  " * indent

    if "$ref" in schema:
        ref_id = schema["$ref"].split('/')[-1]
        if ref_id in visited_schemas:
            schema_str.append(f"{prefix}Reference to: `{ref_id}` (circular/already processed)")
            return "\n".join(schema_str)

        resolved_schema = resolve_ref(schema["$ref"], spec_data, visited_schemas)
        if resolved_schema:
            visited_schemas.add(ref_id) # Mark as visited for this branch
            schema_str.append(f"{prefix}**Schema**: `{ref_id}`")
            schema_str.append(get_schema_details(resolved_schema, spec_data, components, indent + 1, visited_schemas))
            visited_schemas.remove(ref_id) # Unmark after processing this branch
        else:
            schema_str.append(f"{prefix}**Schema**: `{schema['$ref']}` (unresolved)")
    else:
        schema_type = schema.get("type", "object")
        schema_format = schema.get("format")
        schema_enum = schema.get("enum")
        schema_description = schema.get("description")

        type_info = f"Type: `{schema_type}`"
        if schema_format:
            type_info += f", Format: `{schema_format}`"
        if schema_enum:
            type_info += f", Enum: `{', '.join(map(str, schema_enum))}`"

        schema_str.append(f"{prefix}- {type_info}")
        if schema_description:
            schema_str.append(f"{prefix}  {schema_description}")

        if schema_type == "object" and "properties" in schema:
            schema_str.append(f"{prefix}  Properties:")
            for prop_name, prop_schema in schema["properties"].items():
                required_marker = " (required)" if prop_name in schema.get("required", []) else ""
                schema_str.append(f"{prefix}  - `{prop_name}`{required_marker}:")
                schema_str.append(get_schema_details(prop_schema, spec_data, components, indent + 3, visited_schemas))
        elif schema_type == "array" and "items" in schema:
            schema_str.append(f"{prefix}  Items:")
            schema_str.append(get_schema_details(schema["items"], spec_data, components, indent + 3, visited_schemas))

    return "\n
gemini Output

This document provides a comprehensive, professional API documentation for a hypothetical "Product Catalog API v1.0". This output demonstrates the structure, detail, and examples you can expect from the API Documentation Generator, covering endpoint descriptions, request/response examples, authentication guides, and SDK usage examples.


API Documentation: Product Catalog API v1.0

1. Introduction

Welcome to the Product Catalog API v1.0 documentation! This API provides a robust and flexible way to manage your product catalog, allowing you to programmatically create, retrieve, update, and delete product information. It is designed for developers who need to integrate product data into e-commerce platforms, inventory management systems, mobile applications, or custom business intelligence tools.

Our API is built with REST principles, ensuring predictable and resource-oriented URLs, and utilizes standard HTTP response codes for clear communication. All responses are in JSON format.

Key Features:

  • Product Management: Full CRUD (Create, Read, Update, Delete) operations for product entities.
  • Search & Filtering: Efficiently retrieve products based on various criteria.
  • Category Management: Organize products into logical categories.
  • Secure Access: Authenticated access via API keys.

2. Getting Started

This section guides you through the initial steps to interact with the Product Catalog API.

2.1 Base URL

All API requests should be made to the following base URL:

https://api.example.com/v1

2.2 Authentication

The Product Catalog API uses API Key authentication. You must include your unique API key in the X-API-Key HTTP header for every request.

How to Obtain Your API Key:

  1. Log in to your developer portal at [https://developer.example.com](https://developer.example.com).
  2. Navigate to the "API Keys" section.
  3. Generate a new API key or use an existing one.
  4. Keep your API key secure and do not share it publicly.

Example Authentication Header:


X-API-Key: YOUR_API_KEY_HERE

Example cURL Request with Authentication:


curl -X GET \
  https://api.example.com/v1/products \
  -H 'X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx' \
  -H 'Content-Type: application/json'

2.3 Rate Limiting

To ensure fair usage and system stability, the API enforces rate limits.

  • Limit: 100 requests per minute per API key.
  • Response Headers:

* X-RateLimit-Limit: The maximum number of requests allowed in the current window.

* X-RateLimit-Remaining: The number of requests remaining in the current window.

* X-RateLimit-Reset: The time at which the current rate limit window resets (UTC epoch seconds).

If you exceed the rate limit, the API will return a 429 Too Many Requests HTTP status code.

2.4 Error Handling

The API uses standard HTTP status codes to indicate the success or failure of a request. In case of an error (status code 4xx or 5xx), the response body will contain a JSON object with details about the error.

Common Error Structure:


{
  "code": "invalid_parameter",
  "message": "The 'price' parameter must be a positive number.",
  "details": [
    {
      "field": "price",
      "issue": "must be greater than 0"
    }
  ]
}

Common HTTP Status Codes:

| Status Code | Description |

| :---------- | :------------------------------------------- |

| 200 OK | The request was successful. |

| 201 Created | The resource was successfully created. |

| 204 No Content | The request was successful, no content to return. |

| 400 Bad Request | The request was malformed or invalid. |

| 401 Unauthorized | Authentication credentials were missing or invalid. |

| 403 Forbidden | You do not have permission to access the resource. |

| 404 Not Found | The requested resource could not be found. |

| 409 Conflict | The request could not be completed due to a conflict with the current state of the resource. |

| 429 Too Many Requests | You have exceeded the API rate limit. |

| 500 Internal Server Error | An unexpected error occurred on the server. |

3. Endpoints

This section details all available API endpoints, including their methods, paths, descriptions, parameters, and examples.

3.1 Products

Resource: /products


GET /products

Retrieves a list of all products in the catalog. Supports pagination and filtering.

  • Method: GET
  • Path: /products
  • Description: Returns an array of product objects.
  • Query Parameters:

| Parameter | Type | Description | Required | Default |

| :-------- | :----- | :---------------------------------------------- | :------- | :------ |

| limit | integer | Maximum number of products to return (1-100). | No | 20 |

| offset | integer | The number of products to skip. | No | 0 |

| category | string | Filter products by category slug. | No | All |

| search | string | Search products by name or description (partial match). | No | None |

  • Request Example (cURL):

    curl -X GET \
      'https://api.example.com/v1/products?limit=10&category=electronics' \
      -H 'X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx'
  • Request Example (Python):

    import requests

    api_key = "sk_live_xxxxxxxxxxxxxxxxxxxx"
    base_url = "https://api.example.com/v1"

    headers = {
        "X-API-Key": api_key,
        "Content-Type": "application/json"
    }
    params = {
        "limit": 10,
        "category": "electronics"
    }

    try:
        response = requests.get(f"{base_url}/products", headers=headers, params=params)
        response.raise_for_status() # Raise an exception for HTTP errors
        products = response.json()
        print(products)
    except requests.exceptions.HTTPError as err:
        print(f"HTTP error occurred: {err}")
        print(response.json())
    except Exception as err:
        print(f"An error occurred: {err}")
  • Response Example (200 OK):

    {
      "data": [
        {
          "id": "prod_abc123",
          "name": "Wireless Bluetooth Headphones",
          "description": "High-fidelity audio with noise cancellation.",
          "price": 79.99,
          "currency": "USD",
          "category": "electronics",
          "sku": "WH-BT-001",
          "stock_quantity": 150,
          "created_at": "2023-10-26T10:00:00Z",
          "updated_at": "2023-10-26T10:00:00Z"
        },
        {
          "id": "prod_def456",
          "name": "Smart Fitness Tracker",
          "description": "Monitor your heart rate, steps, and sleep.",
          "price": 49.99,
          "currency": "USD",
          "category": "electronics",
          "sku": "FT-SMART-002",
          "stock_quantity": 200,
          "created_at": "2023-10-25T14:30:00Z",
          "updated_at": "2023-10-25T14:30:00Z"
        }
      ],
      "pagination": {
        "limit": 10,
        "offset": 0,
        "total": 25
      }
    }

GET /products/{productId}

Retrieves a single product by its unique ID.

  • Method: GET
  • Path: /products/{productId}
  • Description: Returns a single product object.
  • Path Parameters:

| Parameter | Type | Description | Required |

| :---------- | :------- | :------------------------------------ | :------- |

| productId | string | The unique identifier of the product. | Yes |

  • Request Example (cURL):

    curl -X GET \
      https://api.example.com/v1/products/prod_abc123 \
      -H 'X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx'
  • Response Example (200 OK):

    {
      "id": "prod_abc123",
      "name": "Wireless Bluetooth Headphones",
      "description": "High-fidelity audio with noise cancellation.",
      "price": 79.99,
      "currency": "USD",
      "category": "electronics",
      "sku": "WH-BT-001",
      "stock_quantity": 150,
      "created_at": "2023-10-26T10:00:00Z",
      "updated_at": "2023-10-26T10:00:00Z"
    }
  • Response Example (404 Not Found):

    {
      "code": "not_found",
      "message": "Product with ID 'prod_xyz789' not found."
    }

POST /products

Creates a new product in the catalog.

  • Method: POST
  • Path: /products
  • Description: Creates and returns the newly created product object.
  • Request Body (JSON):

| Parameter | Type | Description | Required |

| :------------- | :-------- | :-------------------------------------------- | :------- |

| name | string | The name of the product. | Yes |

| description | string | A detailed description of the product. | Yes |

| price | number | The price of the product. Must be positive. | Yes |

| currency | string | The currency of the product (e.g., "USD"). | Yes |

| category | string | The slug of the product's category. | Yes |

| sku | string | Stock Keeping Unit (must be unique). | Yes |

| stock_quantity | integer | The initial quantity in stock. Must be non-negative. | Yes |

  • Request Example (cURL):

    curl -X POST \
      https://api.example.com/v1/products \
      -H 'X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx' \
      -H 'Content-Type: application/json' \
      -d '{
            "name": "4K Ultra HD Smart TV",
            "description": "Immersive viewing experience with smart features.",
            "price": 899.99,
            "currency": "USD",
            "category": "electronics",
            "sku": "TV-4K-SMART-001",
            "stock_quantity": 50
          }'
  • Request Example (Python):

    import requests

    api_key = "sk_live_xxxxxxxxxxxxxxxxxxxx"
    base_url = "https://api.example.com/v1"

    headers = {
        "X-API-Key": api_key,
        "Content-Type": "application/json"
    }
    payload = {
        "name": "4K Ultra HD Smart TV",
        "description": "Immersive viewing experience with smart features.",
        "price": 899.99,
        "currency": "USD",
        "category": "electronics",
        "sku": "TV-4K-SMART-001",
        "stock_quantity": 50
    }

    try:
        response = requests.post(f"{base_url}/products", headers=headers, json=payload)
        response.raise_for_status()
        new_product
api_documentation_generator.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( ) "); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react' import './App.css' function App(){ return(

"+slugTitle(pn)+"

Built with PantheraHive BOS

) } export default App "); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e} .app{min-height:100vh;display:flex;flex-direction:column} .app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px} h1{font-size:2.5rem;font-weight:700} "); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` ## Open in IDE Open the project folder in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.13", "vue-router": "^4.4.5", "pinia": "^2.3.0", "axios": "^1.7.9" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "typescript": "~5.7.3", "vite": "^6.0.5", "vue-tsc": "^2.2.0" } } '); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname,'src') } } }) "); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]} '); zip.file(folder+"tsconfig.app.json",'{ "compilerOptions":{ "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"], "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true, "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue", "strict":true,"paths":{"@/*":["./src/*"]} }, "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"] } '); zip.file(folder+"env.d.ts","/// "); zip.file(folder+"index.html"," "+slugTitle(pn)+"
"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.mount('#app') "); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue"," "); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547} "); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` Open in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test" }, "dependencies": { "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^19.0.0", "@angular/forms": "^19.0.0", "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.0.0", "typescript": "~5.6.0" } } '); zip.file(folder+"angular.json",'{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "'+pn+'": { "projectType": "application", "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/'+pn+'", "index": "src/index.html", "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "styles": ["src/styles.css"], "scripts": [] } }, "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"} } } } } '); zip.file(folder+"tsconfig.json",'{ "compileOnSave": false, "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]}, "references":[{"path":"./tsconfig.app.json"}] } '); zip.file(folder+"tsconfig.app.json",'{ "extends":"./tsconfig.json", "compilerOptions":{"outDir":"./dist/out-tsc","types":[]}, "files":["src/main.ts"], "include":["src/**/*.d.ts"] } '); zip.file(folder+"src/index.html"," "+slugTitle(pn)+" "); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch(err => console.error(err)); "); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; } "); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = '"+pn+"'; } "); zip.file(folder+"src/app/app.component.html","

"+slugTitle(pn)+"

Built with PantheraHive BOS

"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1} "); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) ] }; "); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router'; export const routes: Routes = []; "); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install ng serve # or: npm start ``` ## Build ```bash ng build ``` Open in VS Code with Angular Language Service extension. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local .angular/ "); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join(" "):"# add dependencies here "; zip.file(folder+"main.py",src||"# "+title+" # Generated by PantheraHive BOS print(title+" loaded") "); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Run ```bash python main.py ``` "); zip.file(folder+".gitignore",".venv/ __pycache__/ *.pyc .env .DS_Store "); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+" "; zip.file(folder+"package.json",pkgJson); var fallback="const express=require("express"); const app=express(); app.use(express.json()); app.get("/",(req,res)=>{ res.json({message:""+title+" API"}); }); const PORT=process.env.PORT||3000; app.listen(PORT,()=>console.log("Server on port "+PORT)); "; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000 "); zip.file(folder+".gitignore","node_modules/ .env .DS_Store "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash npm install ``` ## Run ```bash npm run dev ``` "); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:" "+title+" "+code+" "; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */ *{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e} "); zip.file(folder+"script.js","/* "+title+" — scripts */ "); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Open Double-click `index.html` in your browser. Or serve locally: ```bash npx serve . # or python3 -m http.server 3000 ``` "); zip.file(folder+".gitignore",".DS_Store node_modules/ .env "); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/**(.+?)**/g,"$1"); hc=hc.replace(/ {2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. Files: - "+app+".md (Markdown) - "+app+".html (styled HTML) "); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); }function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}