API Documentation Generator
Run ID: 69cb4b3461b1021a29a87b1f2026-03-31Development
PantheraHive BOS
BOS Dashboard

API Documentation Generator: Architecture Plan

This document outlines the comprehensive architecture plan for the "API Documentation Generator," a system designed to automate and streamline the creation of professional, detailed, and interactive API documentation. This plan focuses on core components, data flow, key features, technology considerations, and operational aspects to ensure a robust, scalable, and user-friendly solution.


1. Introduction and Objectives

The primary objective of the API Documentation Generator is to transform various API definition sources (e.g., OpenAPI specifications, code annotations) into high-quality, consumable documentation. This includes detailed endpoint descriptions, request/response examples, authentication guides, and SDK usage examples, presented in multiple formats.

Key Objectives:


2. Core Architecture Components

The API Documentation Generator will be built upon a modular architecture, enabling flexibility, scalability, and maintainability.

2.1. Input & Source Integration Layer

This layer is responsible for ingesting API definitions from various sources.

2.2. Parsing & Validation Engine

Once input is received, this engine processes and validates its structure.

2.3. Intermediate Representation (IR) Layer

A standardized, technology-agnostic internal data model representing the API.

2.4. Enrichment & Customization Layer

This layer allows for adding supplementary content and customizing the documentation beyond what's available in the raw API definition.

* Extended descriptions for APIs, endpoints, parameters.

* Detailed tutorials and guides.

* Manual request/response examples.

* SDK usage examples (if not auto-generated).

* Glossaries, FAQs, and other supporting documentation.

2.5. Template Engine & Renderer

Responsible for transforming the enriched IR into renderable content using predefined or custom templates.

2.6. Output Formatter & Storage Layer

Generates the final documentation in various formats and manages its persistence.

2.7. User Interface (UI) / API Layer

The primary interface for users to interact with the generator.

2.8. Authentication & Authorization Module

Manages secure access to the generator and its functionalities.


3. Data Flow Diagram (Conceptual)

mermaid • 517 chars
graph TD
    A[API Definition Sources] --> B(Input & Source Integration Layer)
    B --> C(Parsing & Validation Engine)
    C --> D(Intermediate Representation - IR)
    D -- User Input/Customization --> E(Enrichment & Customization Layer)
    E --> F(Template Engine & Renderer)
    F --> G(Output Formatter & Storage Layer)
    G --> H[Published Documentation]
    I[User Interface / API] -- Manage APIs, Templates, Trigger Generation --> A
    I -- Manage Custom Content --> E
    I -- Access Generated Docs --> H
Sandboxed live preview

Explanation:

  1. API Definition Sources (e.g., OpenAPI files, code, VCS) feed into the Input & Source Integration Layer.
  2. The Parsing & Validation Engine processes and validates these inputs, creating a Intermediate Representation (IR).
  3. The Enrichment & Customization Layer allows users (via UI/API) to add supplementary content and configure generation settings, enriching the IR.
  4. The enriched IR is then passed to the Template Engine & Renderer, which applies selected templates.
  5. The Output Formatter & Storage Layer converts the rendered content into final documentation formats and stores them.
  6. Published Documentation is then accessible to end-users.
  7. The User Interface / API provides a central control point for managing the entire process.

4. Key Features & Functionality

The generator will support a comprehensive set of features:

4.1. Input & Sync

  • OpenAPI/Swagger Support: Full compatibility with OpenAPI Specification v2.0 and v3.x.
  • Postman Collection Import: Ability to import Postman collections for documentation generation.
  • Git Integration: Automatic synchronization with Git repositories for API definition files.
  • Manual Upload: Option to upload API definition files directly.
  • Webhooks: Support for webhooks to trigger documentation updates upon code/definition changes.

4.2. Documentation Content

  • Endpoint Details: Comprehensive descriptions of paths, methods, parameters (path, query, header, cookie), request bodies, and responses.
  • Schema Definitions: Detailed explanation of data models used in requests and responses.
  • Authentication Guides: Clear instructions for various authentication methods (API Key, OAuth2, Basic Auth, Bearer Token).
  • Request/Response Examples: Automatically generated or manually provided examples in JSON, XML, or other formats.
  • Code Snippets: Auto-generated code examples for common languages (cURL, Python, Node.js, Java, Go, Ruby, PHP, C#).
  • SDK Usage Examples: Demonstrations of how to use generated SDKs (if integrated) or custom SDKs.
  • Markdown Support: Rich text editing for descriptions, overviews, and custom sections using Markdown.
  • Tutorials & Guides: Ability to add extensive tutorials, setup guides, and best practices.

4.3. Customization & Branding

  • Custom Templates: Upload and manage custom HTML/CSS/JS templates for unique branding.
  • Theme Editor: Built-in tools to customize colors, fonts, and layout of standard templates.
  • Logo & Favicon: Branding options for the generated documentation.

4.4. Output & Publishing

  • Interactive HTML: Dynamic documentation with search, navigation, "Try it out" console, and dark mode.
  • Static HTML: Generate static HTML files for easy hosting.
  • Markdown Export: Export documentation to Markdown format for internal use or other platforms.
  • PDF Export: Generate print-ready PDF documentation.
  • Postman Collection Export: Export enriched API definitions back into Postman Collection format.
  • Version Control: Manage different versions of API documentation linked to API versions.
  • Publishing Options: Direct deployment to hosting services (e.g., S3, Netlify) or download options.

4.5. Management & Collaboration

  • API Project Management: Organize multiple APIs into projects.
  • User & Role Management: Control who can create, edit, and publish documentation.
  • Preview Functionality: Real-time preview of documentation before publishing.
  • Audit Trails: Log changes made to API definitions and documentation.

5. Proposed Technology Stack

This section outlines a recommended technology stack, chosen for its robustness, scalability, and developer ecosystem.

5.1. Backend

  • Language: Python (Django/Flask) or Node.js (Express/NestJS)

Rationale:* Mature ecosystems for web services, data processing, and integration with various tools. Python is strong for data parsing and scripting, Node.js for high-concurrency I/O operations.

  • API Definition Parsing:

* Python: pyyaml, jsonschema, openapi-spec-validator

* Node.js

gemini Output

As part of the "API Documentation Generator" workflow, we are now executing the generate_code step. This deliverable provides a comprehensive, detailed, and production-ready Python-based API documentation generator. It takes an OpenAPI Specification as input and produces well-structured, professional HTML documentation, including endpoint descriptions, request/response examples, authentication guides, and API call snippets.


API Documentation Generator: Code Deliverable

This document outlines and provides the code for a robust API documentation generator. This tool is designed to automate the process of creating high-quality, interactive API documentation from a standard OpenAPI Specification (OAS).

1. Introduction

The goal of this generator is to transform a machine-readable OpenAPI Specification into human-readable, professional HTML documentation. It focuses on clarity, completeness, and ease of navigation, ensuring that developers can quickly understand and integrate with your API.

2. Core Concept and Architecture

The generator follows a standard pipeline:

  1. Input: Reads an OpenAPI Specification (YAML or JSON).
  2. Parsing: Processes the OpenAPI data into a structured Python object model.
  3. Templating: Uses Jinja2, a powerful templating engine, to render the structured data into HTML.
  4. Output: Generates a set of static HTML files (and supporting assets) that constitute the complete documentation.

Key Architectural Components:

  • main.py: The entry point and orchestrator, handling command-line arguments, loading the spec, and coordinating the parsing and rendering.
  • api_parser.py: Responsible for loading and normalizing the OpenAPI specification, extracting key information like endpoints, schemas, and security schemes.
  • doc_renderer.py: Manages the Jinja2 environment, loads templates, and renders the processed API data into HTML files.
  • code_examples.py: Generates generic API call examples (e.g., cURL, Python requests, JavaScript fetch) based on endpoint definitions.
  • templates/: A directory containing Jinja2 template files (.html) that define the structure and presentation of the documentation.
  • static/: (Conceptual) A directory for static assets like CSS, JavaScript, and images, which would be copied to the output directory.

3. Project Setup and Installation

Prerequisites

  • Python 3.8+

Directory Structure


api-doc-generator/
├── src/
│   ├── api_parser.py
│   ├── code_examples.py
│   ├── config.py
│   ├── doc_renderer.py
│   ├── main.py
│   └── templates/
│       ├── base.html
│       ├── index.html
│       ├── endpoint.html
│       ├── schema.html
│       └── components/
│           ├── _header.html
│           ├── _sidebar.html
│           ├── _footer.html
│           ├── _method_card.html
│           └── _schema_details.html
├── static/
│   ├── css/
│   │   └── style.css
│   └── js/
│       └── main.js
├── example_api_spec.yaml
├── requirements.txt
└── README.md

requirements.txt


PyYAML>=6.0
Jinja2>=3.1.2

To install the dependencies:


pip install -r requirements.txt

4. Code Implementation

4.1. src/config.py

This file holds configuration constants for the generator.


# src/config.py

import os

# Base directory for the project
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Path to the templates directory
TEMPLATES_DIR = os.path.join(BASE_DIR, 'src', 'templates')

# Path to the static assets directory
STATIC_DIR = os.path.join(BASE_DIR, 'static')

# Default output directory for generated documentation
DEFAULT_OUTPUT_DIR = os.path.join(BASE_DIR, 'docs')

# Default OpenAPI spec file name
DEFAULT_SPEC_FILE = 'example_api_spec.yaml'

# Default title for the documentation
DEFAULT_DOC_TITLE = "API Documentation"

4.2. src/api_parser.py

Handles the loading and parsing of the OpenAPI specification. It extracts and structures the data needed for templating.


# src/api_parser.py

import yaml
import json
import os
from collections import defaultdict

class OpenAPIParser:
    """
    Parses an OpenAPI Specification file (YAML or JSON) and extracts relevant
    information for documentation generation.
    """
    def __init__(self, spec_path):
        if not os.path.exists(spec_path):
            raise FileNotFoundError(f"OpenAPI spec file not found: {spec_path}")
        self.spec_path = spec_path
        self.spec = self._load_spec()
        self.api_data = {} # Stores processed API data

    def _load_spec(self):
        """Loads the OpenAPI spec from the given path."""
        with open(self.spec_path, 'r', encoding='utf-8') as f:
            if self.spec_path.endswith(('.yaml', '.yml')):
                return yaml.safe_load(f)
            elif self.spec_path.endswith('.json'):
                return json.load(f)
            else:
                raise ValueError("Unsupported spec file format. Must be .yaml, .yml, or .json")

    def _resolve_ref(self,
gemini Output

PantheraHive Product Catalog API Documentation

Welcome to the official documentation for the PantheraHive Product Catalog API. This API allows you to programmatically manage your product catalog, including retrieving product information, adding new products, updating existing ones, and deleting products.

This document provides detailed information on available endpoints, authentication methods, request/response structures, and examples to help you integrate seamlessly with our services.


1. Introduction

The PantheraHive Product Catalog API provides a robust and flexible interface for managing your product data. It is designed for developers who need to integrate product information into their applications, e-commerce platforms, or internal systems.

Key Features:

  • Retrieve comprehensive product details.
  • Filter and paginate product listings.
  • Create new product entries.
  • Update existing product information.
  • Delete products from the catalog.

2. Base URL

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

https://api.pantherahive.com/v1


3. Authentication

The PantheraHive Product Catalog API uses API Key authentication. To authenticate your requests, you must include your unique API Key in the X-API-Key header for every request.

How to obtain your API Key:

  1. Log in to your PantheraHive developer dashboard.
  2. Navigate to the "API Keys" section.
  3. Generate a new API Key if you don't have one, or use an existing active key.

Example Request Header:


X-API-Key: YOUR_API_KEY_HERE
Content-Type: application/json

Important:

  • Keep your API Key secure and do not expose it in client-side code or public repositories.
  • If your API Key is compromised, revoke it immediately from your developer dashboard and generate a new one.

4. Endpoints

This section details all available API endpoints, their methods, parameters, and example requests/responses.

4.1. List All Products

Retrieve a paginated list of all products in the catalog.

  • URL: /products
  • Method: GET
  • Description: Returns an array of product objects. Supports pagination and filtering.

Query Parameters:

| Parameter | Type | Required | Description | Example |

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

| limit | Integer | No | Maximum number of products to return (default: 10, max: 100) | ?limit=20 |

| offset | Integer | No | Number of products to skip (for pagination) | ?offset=10 |

| category| String | No | Filter products by category | ?category=electronics |

| min_price| Decimal | No | Filter products by minimum price | ?min_price=50.00 |

| max_price| Decimal | No | Filter products by maximum price | ?max_price=200.00|

Example Request (cURL):


curl -X GET \
  'https://api.pantherahive.com/v1/products?limit=5&category=electronics' \
  -H 'X-API-Key: YOUR_API_KEY_HERE'

Example Response (200 OK):


{
  "data": [
    {
      "id": "prod_001",
      "name": "Panthera Smartwatch X1",
      "description": "Next-generation smartwatch with health tracking.",
      "category": "electronics",
      "price": 299.99,
      "currency": "USD",
      "stock": 150,
      "sku": "PH-SMART-X1",
      "created_at": "2023-10-26T10:00:00Z",
      "updated_at": "2023-10-26T10:00:00Z"
    },
    {
      "id": "prod_002",
      "name": "Panthera Wireless Earbuds Pro",
      "description": "Premium noise-cancelling earbuds.",
      "category": "electronics",
      "price": 149.99,
      "currency": "USD",
      "stock": 300,
      "sku": "PH-EARBUDS-PRO",
      "created_at": "2023-10-25T14:30:00Z",
      "updated_at": "2023-10-25T14:30:00Z"
    }
  ],
  "meta": {
    "total": 25,
    "limit": 5,
    "offset": 0,
    "next_offset": 5
  }
}

4.2. Get Product by ID

Retrieve detailed information for a specific product using its unique ID.

  • URL: /products/{product_id}
  • Method: GET
  • Description: Returns a single product object if found.

Path Parameters:

| Parameter | Type | Required | Description | Example |

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

| product_id | String | Yes | The unique ID of the product | prod_001 |

Example Request (cURL):


curl -X GET \
  'https://api.pantherahive.com/v1/products/prod_001' \
  -H 'X-API-Key: YOUR_API_KEY_HERE'

Example Response (200 OK):


{
  "id": "prod_001",
  "name": "Panthera Smartwatch X1",
  "description": "Next-generation smartwatch with health tracking.",
  "category": "electronics",
  "price": 299.99,
  "currency": "USD",
  "stock": 150,
  "sku": "PH-SMART-X1",
  "created_at": "2023-10-26T10:00:00Z",
  "updated_at": "2023-10-26T10:00:00Z"
}

Example Response (404 Not Found):


{
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "Product with ID 'non_existent_id' not found."
  }
}

4.3. Create New Product

Add a new product to the catalog.

  • URL: /products
  • Method: POST
  • Description: Creates a new product entry and returns the newly created product object.

Request Body (application/json):

| Parameter | Type | Required | Description | Example |

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

| name | String | Yes | Name of the product | "Panthera Laptop Pro" |

| description| String | Yes | Detailed description of the product | "High-performance laptop for professionals." |

| category | String | Yes | Product category (e.g., "electronics", "books") | "electronics" |

| price | Decimal | Yes | Price of the product | 1299.99 |

| currency | String | Yes | Currency code (e.g., "USD", "EUR") | "USD" |

| stock | Integer | Yes | Current stock quantity | 50 |

| sku | String | No | Stock Keeping Unit (unique identifier) | "PH-LAPTOP-PRO" |

| image_url| String | No | URL to the product image | "https://example.com/laptop.jpg" |

Example Request (cURL):


curl -X POST \
  'https://api.pantherahive.com/v1/products' \
  -H 'X-API-Key: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Panthera Laptop Pro",
    "description": "High-performance laptop for professionals.",
    "category": "electronics",
    "price": 1299.99,
    "currency": "USD",
    "stock": 50,
    "sku": "PH-LAPTOP-PRO",
    "image_url": "https://example.com/laptop_pro.jpg"
  }'

Example Response (201 Created):


{
  "id": "prod_003",
  "name": "Panthera Laptop Pro",
  "description": "High-performance laptop for professionals.",
  "category": "electronics",
  "price": 1299.99,
  "currency": "USD",
  "stock": 50,
  "sku": "PH-LAPTOP-PRO",
  "image_url": "https://example.com/laptop_pro.jpg",
  "created_at": "2023-11-01T09:15:00Z",
  "updated_at": "2023-11-01T09:15:00Z"
}

Example Response (400 Bad Request - Missing Field):


{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request body.",
    "details": [
      {
        "field": "name",
        "message": "Product name is required."
      }
    ]
  }
}

4.4. Update Existing Product

Update specific fields of an existing product.

  • URL: /products/{product_id}
  • Method: PUT (for full replacement) or PATCH (for partial update)
  • Description: Updates an existing product. Only fields provided in the request body will be modified.

Path Parameters:

| Parameter | Type | Required | Description | Example |

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

| product_id | String | Yes | The unique ID of the product | prod_001 |

Request Body (application/json) - for PATCH (partial update):

| Parameter | Type | Required | Description | Example |

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

| name | String | No | New name of the product | "Panthera Smartwatch X2" |

| description| String | No | Updated description | "Advanced smartwatch with improved battery." |

| price | Decimal | No | New price of the product | 319.99 |

| stock | Integer | No | New stock quantity | 120 |

Example Request (cURL - PATCH):


curl -X PATCH \
  'https://api.pantherahive.com/v1/products/prod_001' \
  -H 'X-API-Key: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Panthera Smartwatch X2",
    "price": 319.99,
    "stock": 120
  }'

Example Response (200 OK):


{
  "id": "prod_001",
  "name": "Panthera Smartwatch X2",
  "description": "Next-generation smartwatch with health tracking.",
  "category": "electronics",
  "price": 319.99,
  "currency": "USD",
  "stock": 120,
  "sku": "PH-SMART-X1",
  "created_at": "2023-10-26T10:00:00Z",
  "updated_at": "2023-11-01T11:00:00Z"
}

4.5. Delete Product

Remove a product from the catalog.

  • URL: /products/{product_id}
  • Method: DELETE
  • Description: Deletes the product with the specified ID.

Path Parameters:

| Parameter | Type | Required | Description | Example |

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

| product_id | String | Yes | The unique ID of the product | prod_002 |

Example Request (cURL):


curl -X DELETE \
  'https://api.pantherahive.com/v1/products/prod_002' \
  -H 'X-API-Key: YOUR_API_KEY_HERE'

Example Response (204 No Content):

A successful deletion will return an empty response body with a 204 No Content status code.

Example Response (404 Not Found):


{
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "Product with ID 'non_existent_id' not found."
  }
}

5. Error Handling

The PantheraHive Product Catalog API uses standard HTTP status codes to indicate the success or failure of an API request. In case of an error, a JSON response body will provide more details.

| HTTP Status Code | Description | Error Code (JSON) |

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

| 200 OK | The request was successful. | |

| 201 Created |

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
\n\n\n"); 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'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); 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'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- 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",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); 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'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); 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}\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- 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",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "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"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); 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';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); 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}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/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("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/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)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- 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:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== 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(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } 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);}});}