API Documentation Writer
Run ID: 69cbb91c61b1021a29a8baf52026-03-31Development
PantheraHive BOS
BOS Dashboard

PantheraHive Notification API Documentation

Welcome to the PantheraHive Notification API documentation! This guide provides comprehensive details on how to integrate with our robust notification system, enabling you to send, manage, and retrieve notifications programmatically. Our API is designed for developers, offering a powerful and flexible way to enhance user engagement and communication within your applications.


Overview: Connecting Your Application to PantheraHive Notifications

The PantheraHive Notification API allows you to seamlessly integrate custom, real-time notifications into your platform. Whether you need to alert users about new activity, important updates, or critical events, our API provides the tools to deliver timely and relevant information.

Key Capabilities:

This documentation will guide you through the authentication process, available endpoints, request/response formats, and best practices for building reliable integrations.


Getting Started

To begin using the PantheraHive Notification API, you'll need an API Key. Follow these steps:

  1. Sign Up/Log In: Create an account or log in to your PantheraHive Developer Dashboard.
  2. Generate API Key: Navigate to the "API Settings" section and generate a new API Key. Keep this key secure and do not expose it in client-side code.
  3. Start Building: Use the examples provided in this documentation to make your first API calls.

API Reference

Base URL

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

https://api.pantherahive.com/v1

Authentication

The PantheraHive Notification API uses API Key authentication. You must include your API Key in the Authorization header of every request.

Header Format:

Authorization: Bearer YOUR_API_KEY

Example:

text • 61 chars
Authorization: Bearer ph_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Sandboxed live preview

Step 1 of 3: Research Topic - Comprehensive API Documentation Foundation

This step focuses on generating a detailed research plan to lay a robust foundation for professional API documentation. The goal is to gather all necessary information about the API, its target audience, business context, and technical specifications to ensure the documentation is accurate, complete, and highly usable.


1. Understanding the API's Core Functionality and Purpose

Before writing a single line, it's crucial to grasp the fundamental 'why' and 'what' of the API.

  • API Overview and Value Proposition:

* What primary problem does this API solve for developers?

* What unique value does it offer compared to alternatives?

* What are its core capabilities and limitations?

* What are the key business objectives or use cases it enables?

  • High-Level Architecture and Design Principles:

* Is it a RESTful, GraphQL, SOAP, gRPC, or another type of API?

* What are the core design philosophies (e.g., idempotency, statelessness)?

* Are there any microservices or underlying systems that impact its behavior?

2. Deep Dive into Technical Specifications

This section covers the granular details required to accurately describe how to interact with the API.

  • Endpoints and Methods:

* List all available endpoints (URIs).

* Identify the HTTP methods (GET, POST, PUT, DELETE, PATCH) supported by each endpoint.

* Understand the purpose and expected behavior of each method for every resource.

  • Request and Response Structures:

* Parameters: Identify all path, query, header, and body parameters for each request.

* Data types (string, integer, boolean, array, object).

* Constraints (min/max length, regex, allowed values).

* Required vs. optional status.

* Default values.

* Description and purpose of each parameter.

* Request Body: Document the JSON/XML/form-data structure for POST/PUT/PATCH requests.

* Example request payloads.

* Schema definitions.

* Response Body: Document the expected JSON/XML structure for successful and error responses.

* Example response payloads for various scenarios.

* Schema definitions for response objects.

  • Authentication and Authorization:

* What authentication schemes are supported (e.g., API Key, OAuth 2.0, JWT, Basic Auth)?

* How is authentication implemented (e.g., header, query parameter)?

* What are the authorization scopes or permissions required for different operations?

* How to obtain credentials (e.g., developer portal, registration process)?

  • Status Codes and Error Handling:

* List all possible HTTP status codes returned by the API (2xx, 3xx, 4xx, 5xx).

* Provide detailed explanations for each status code.

* Document the structure of error responses, including error codes, messages, and potential solutions.

* Explain common error scenarios and how developers can debug them.

  • Rate Limiting and Throttling:

* Are there any rate limits imposed on API calls?

* How are rate limits communicated (e.g., HTTP headers)?

* What is the behavior when rate limits are exceeded?

  • Pagination and Filtering:

* How are large datasets retrieved (e.g., cursor-based, offset-based pagination)?

* What parameters are available for filtering, sorting, and searching data?

  • Webhooks and Asynchronous Operations:

* If applicable, how do webhooks work?

* What events trigger webhooks?

* What is the payload structure for webhook notifications?

* How are asynchronous operations initiated and monitored?

  • SDKs, Client Libraries, and Code Examples:

* Are there any official or community-contributed SDKs?

* What programming languages are primarily targeted for code examples?

* Access to working code samples and their environments.

3. Target Audience Analysis

Understanding who will use the documentation is critical for tailoring its content, tone, and depth.

  • Developer Personas:

* Primary Audience: E.g., Frontend developers, Backend engineers, Mobile developers, Data scientists, Integrators.

* Technical Proficiency: Are they beginners, intermediate, or expert API users? Do they have domain-specific knowledge?

* Goals: What are their main objectives when using this API (e.g., build a new feature, integrate with an existing system, automate a workflow)?

* Pain Points: What challenges might they face? What information do they typically look for first?

  • Use Cases:

* Identify the most common and critical use cases developers will implement with the API.

* Prioritize these use cases for tutorials and quick-start guides.

4. Business Context and Stakeholder Engagement

Gathering insights from various internal teams provides a holistic view and ensures alignment.

  • Product Management:

* API vision, roadmap, and future enhancements.

* Key features, business goals, and metrics.

* Competitive landscape and differentiation.

  • Engineering/Development Team:

* Technical design decisions and rationale.

* Implementation details, potential edge cases, and known limitations.

* Testing environment access and best practices.

* Internal documentation, code comments, and existing specifications (e.g., OpenAPI/Swagger files).

  • Support/Customer Success Teams:

* Common customer questions, issues, and FAQs related to the API.

* Areas where existing documentation might be unclear or incomplete.

  • Sales/Marketing Teams:

* Value proposition messaging and key benefits for developers.

* Integration stories or success cases.

  • Legal/Compliance:

* Terms of Service, Privacy Policy implications, data handling requirements (e.g., GDPR, CCPA).

5. Existing Documentation and Resources Review

Leverage any pre-existing materials to ensure consistency and avoid duplication of effort.

  • Internal Specifications:

* OpenAPI/Swagger definitions (crucial for accurate endpoint and schema details).

* Design documents, architecture diagrams, data models.

* Git repositories (READMEs, code comments).

  • Previous Documentation Versions:

* Identify what worked well and what needed improvement.

* Note any deprecated features or breaking changes.

  • Competitor Analysis:

* Review documentation from similar APIs to identify industry best practices, common structures, and potential gaps in current plans.

  • Developer Forums/Community:

* Monitor discussions, questions, and feedback from existing API users to identify common pain points and areas needing clarification.

6. Tools and Environment Setup

Ensure access to the necessary tools and environments for effective documentation.

  • API Testing Tools:

* Access to Postman collections, Insomnia workspaces, or similar tools for testing endpoints.

  • Development Environment:

* Access to a sandbox or development environment to verify code examples and API behavior.

  • Documentation Platform:

* Familiarity with the chosen documentation generation tool (e.g., ReadMe.io, Docusaurus, Swagger UI, custom portal).

  • Version Control:

* Access to Git repositories for managing documentation source code.


By thoroughly researching these areas, the API Documentation Writer will be equipped with a comprehensive understanding, enabling the creation of accurate, user-friendly, and highly effective API documentation.

Security Best Practices:

  • Always keep your API Key confidential.
  • Do not embed your API Key directly into front-end code (e.g., JavaScript in a browser).
  • Use environment variables or a secure configuration management system to store your API Key.
  • For server-to-server communication, ensure your server environment is secure.

Error Handling

The API uses standard HTTP status codes to indicate the success or failure of a request. In case of an error, the API will return a JSON object containing details about the error.

| HTTP Status Code | Description | Error Object Example |

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

| 200 OK | Request successful. | - |

| 201 Created | Resource successfully created. | - |

| 400 Bad Request| Invalid request payload or parameters. | { "code": "invalid_request", "message": "Missing required field: recipientId" } |

| 401 Unauthorized| Authentication failed or missing. | { "code": "unauthorized", "message": "Invalid or missing API key" } |

| 403 Forbidden | API Key lacks necessary permissions. | { "code": "forbidden", "message": "API Key does not have permission to send SMS"} |

| 404 Not Found | The requested resource does not exist. | { "code": "not_found", "message": "Notification with ID 'xyz' not found" } |

| 429 Too Many Requests| Rate limit exceeded. | { "code": "rate_limited", "message": "Too many requests. Please try again later."}|

| 500 Internal Server Error| An unexpected error occurred on the server. | { "code": "internal_error", "message": "An unexpected error occurred." } |

Rate Limiting

To ensure fair usage and system stability, the PantheraHive Notification API imposes rate limits. Currently, you are limited to:

  • 100 requests per second per API Key.

If you exceed the rate limit, the API will return a 429 Too Many Requests HTTP status code. We recommend implementing a retry mechanism with exponential backoff in your application to handle rate limit errors gracefully.


Endpoints

1. Send a New Notification

Send a custom notification to a specified recipient.

  • Endpoint: /notifications
  • Method: POST
  • Description: Creates and dispatches a new notification. The notification type (e.g., email, in-app) is determined by the channel field.

Request Body Parameters:

| Parameter | Type | Required | Description

gemini Output

This document outlines the comprehensive, detailed, and professional API documentation for the Acme Product Management API. This output has been meticulously polished and formatted to ensure clarity, usability, and adherence to industry best practices, making it a ready-to-use deliverable for developers integrating with the API.


Acme Product Management API Documentation

Welcome to the Acme Product Management API documentation. This API provides a robust and flexible way to manage your product catalog, including creating, retrieving, updating, and deleting product information. It is designed for developers who need to integrate product data into various applications, websites, or services.

Table of Contents

  1. [Introduction](#1-introduction)
  2. [Base URL](#2-base-url)
  3. [Authentication](#3-authentication)

* [API Key Authentication](#api-key-authentication)

* [Generating an API Key](#generating-an-api-key)

  1. [Error Handling](#4-error-handling)
  2. [Rate Limiting](#5-rate-limiting)
  3. [Endpoints](#6-endpoints)

* [Products](#products)

* [GET /products](#get-products)

* [GET /products/{productId}](#get-products-productid)

* [POST /products](#post-products)

* [PUT /products/{productId}](#put-products-productid)

* [DELETE /products/{productId}](#delete-products-productid)

  1. [Data Models](#7-data-models)

* [Product Object](#product-object)

* [Error Object](#error-object)

  1. [Code Examples](#8-code-examples)

* [cURL](#curl)

* [Python](#python)

* [JavaScript (Node.js)](#javascript-nodejs)

  1. [Versioning](#9-versioning)
  2. [Support and Feedback](#10-support-and-feedback)
  3. [Changelog](#11-changelog)

1. Introduction

The Acme Product Management API allows programmatic access to your product inventory. You can perform standard CRUD (Create, Read, Update, Delete) operations on product resources, enabling seamless integration with your existing systems. This documentation will guide you through the API's structure, authentication methods, available endpoints, and data models.

2. Base URL

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

https://api.acme.com/v1

3. Authentication

The Acme Product Management API uses API Key authentication. All requests to protected endpoints must include a valid API Key in the Authorization header.

API Key Authentication

Your API Key must be sent in the Authorization header with the Bearer scheme.

Header Example:


Authorization: Bearer YOUR_API_KEY

Replace YOUR_API_KEY with your actual API Key. Failing to provide a valid API Key will result in a 401 Unauthorized error.

Generating an API Key

To generate an API Key:

  1. Log in to your Acme Developer Dashboard.
  2. Navigate to the "API Keys" section.
  3. Click "Generate New Key."
  4. Copy your API Key immediately, as it will only be shown once.

For security reasons, treat your API Key as a sensitive credential and keep it confidential.

4. Error Handling

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

| HTTP Status Code | Description | Error Type |

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

| 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. | invalid_request |

| 401 Unauthorized| Authentication credentials are missing or invalid. | unauthorized |

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

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

| 405 Method Not Allowed| The HTTP method used is not supported for this endpoint. | method_not_allowed|

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

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

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

Error Response Example:


{
  "code": "invalid_request",
  "message": "Validation failed: 'name' is required.",
  "details": [
    {
      "field": "name",
      "issue": "is required"
    }
  ]
}

See [Error Object](#error-object) for the schema.

5. Rate Limiting

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

  • Requests per minute: 100 requests per minute per API key.

If you exceed the rate limit, you will receive a 429 Too Many Requests response. The response headers will include:

  • 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 UTC epoch seconds when the current rate limit window resets.

We recommend implementing exponential backoff in your client applications to gracefully handle rate limit errors.

6. Endpoints

This section details all available API endpoints, including their HTTP methods, paths, parameters, request bodies, and response schemas.

Products

Manage your product catalog.

GET /products

Retrieves a list of all products.

Method: GET

Path: /products

Description:

Returns an array of product objects. Supports pagination and filtering.

Query Parameters:

| Name | Type | Required | Description | Default |

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

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

| offset | integer| No | Number of products to skip for pagination. | 0 |

| category| string | No | Filter products by category name. | null |

| q | string | No | Search term to filter products by name or description. | null |

Responses:

  • 200 OK

* Description: A list of product objects.

* Schema: array of [Product Object](#product-object)

* Example:


        [
          {
            "id": "prod_12345",
            "name": "Laptop Pro 15",
            "description": "High-performance laptop for professionals.",
            "price": 1299.99,
            "currency": "USD",
            "category": "Electronics",
            "sku": "LP15-PRO-001",
            "stock": 50,
            "isActive": true,
            "createdAt": "2023-01-15T10:00:00Z",
            "updatedAt": "2023-01-15T10:00:00Z"
          },
          {
            "id": "prod_67890",
            "name": "Wireless Mouse X1",
            "description": "Ergonomic wireless mouse with customizable buttons.",
            "price": 49.99,
            "currency": "USD",
            "category": "Accessories",
            "sku": "WM-X1-BLU",
            "stock": 200,
            "isActive": true,
            "createdAt": "2023-02-01T11:30:00Z",
            "updatedAt": "2023-02-01T11:30:00Z"
          }
        ]

GET /products/{productId}

Retrieves a single product by its ID.

Method: GET

Path: /products/{productId}

Description:

Returns a single product object matching the provided productId.

Path Parameters:

| Name | Type | Required | Description |

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

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

Responses:

  • 200 OK

* Description: The requested product object.

* Schema: [Product Object](#product-object)

* Example:


        {
          "id": "prod_12345",
          "name": "Laptop Pro 15",
          "description": "High-performance laptop for professionals.",
          "price": 1299.99,
          "currency": "USD",
          "category": "Electronics",
          "sku": "LP15-PRO-001",
          "stock": 50,
          "isActive": true,
          "createdAt": "2023-01-15T10:00:00Z",
          "updatedAt": "2023-01-15T10:00:00Z"
        }
  • 404 Not Found

* Description: Product with the specified productId was not found.

* Schema: [Error Object](#error-object)

POST /products

Creates a new product.

Method: POST

Path: /products

Description:

Adds a new product to the catalog. The id, createdAt, and updatedAt fields will be generated by the server.

Request Body:

  • Schema: [Product Object](#product-object) (excluding id, createdAt, updatedAt)
  • Required Fields: name, price, currency, category, sku
  • Example:

    {
      "name": "Gaming Keyboard RGB",
      "description": "Mechanical gaming keyboard with customizable RGB lighting.",
      "price": 99.99,
      "currency": "USD",
      "category": "Accessories",
      "sku": "GK-RGB-001",
      "stock": 150,
      "isActive": true
    }

Responses:

  • 201 Created

* Description: The newly created product object.

* Schema: [Product Object](#product-object)

* Example:


        {
          "id": "prod_98765",
          "name": "Gaming Keyboard RGB",
          "description": "Mechanical gaming keyboard with customizable RGB lighting.",
          "price": 99.99,
          "currency": "USD",
          "category": "Accessories",
          "sku": "GK-RGB-001",
          "stock": 150,
          "isActive": true,
          "createdAt": "2023-03-10T14:30:00Z",
          "updatedAt": "2023-03-10T14:30:00Z"
        }
  • 400 Bad Request

* Description: Invalid request body (e.g., missing required fields, invalid data types).

* Schema: [Error Object](#error-object)

  • 409 Conflict

* Description: A product with the provided sku already exists.

* Schema: [Error Object](#error-object)

PUT /products/{productId}

Updates an existing product.

Method: PUT

Path: /products/{productId}

Description:

Updates all fields of an existing product identified by productId. All fields in the request body are required to be present, even if their values are unchanged (full replacement). For partial updates, use PATCH (not currently supported).

Path Parameters:

| Name | Type | Required | Description |

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

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

Request Body:

  • Schema: [Product Object](#product-object) (excluding id, createdAt, updatedAt)
  • Required Fields: name, price, currency, category, sku, stock, isActive
  • Example:

    {
      "name": "Gaming Keyboard RGB (Updated)",
      "description": "Mechanical gaming keyboard with customizable RGB lighting. Now with improved switches!",
      "price": 109.99,
      "currency": "USD",
      "category": "Accessories",
      "sku": "GK-RGB-001",
      "stock": 120,
      "isActive": true
    }

Responses:

  • 200 OK

* Description: The updated product object.

* Schema: [Product Object](#product-object)

* Example:


        {
          "id": "prod_98765",
          "name": "Gaming Keyboard RGB (Updated)",
          "description": "Mechanical gaming keyboard with customizable RGB lighting. Now with improved switches!",
          "price": 109.99,
          "currency": "USD",
          "category": "Accessories",
          "sku": "GK-RGB-001",
          "stock": 120,
api_documentation_writer.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);}});}