diff --git a/.gitignore b/.gitignore index 8334d6b..dd3ecdd 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,11 @@ coverage .next/ out/ build -dist +# dist - Allow prebuilt packages for quick startup +packages/*/dist/ +!packages/react/dist/ +!packages/render/dist/ +!packages/htmldocs/dist/ # Playwright **/playwright-report diff --git a/README.md b/README.md index 98e74ef..d9a52f1 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ htmldocs is a local document editor and preview server to help you _create_ PDFs - 🔗 Full TypeScript support for type safety - ⚡ Dynamic data integration through props and APIs - 📊 Real-time preview server with hot reloading +- 🚀 **Zero-build development** - modify templates and see changes instantly +- 🏗️ **Monorepo architecture** with pnpm workspaces and Turbo +- 🔄 **Workspace dependencies** - automatic linking between packages ## Example @@ -60,6 +63,76 @@ npx htmldocs@latest init For further instructions or to integrate htmldocs into your existing project, refer to the [Getting Started](https://docs.htmldocs.com/getting-started) guide. +## Development Workflow + +htmldocs supports a **zero-build development experience** for rapid template iteration. You can modify template files and see changes instantly without any build step. + +### One-Click Development + +For the fastest setup, use our development script: + +```bash +# Start zero-build development (from project root) +./dev.sh + +# Or using npm/pnpm script +pnpm dev:zero-build +``` + +This script will: +- ✅ Install tsx if needed +- ✅ Build core dependencies (one-time) +- ✅ Start development server with hot reload +- ✅ Open examples at http://localhost:3000 + +### Manual Setup + +```bash +# 1. Install dependencies +pnpm install + +# 2. Build core dependencies (one-time only) +cd packages/react && pnpm build +cd ../render && pnpm build + +# 3. Install TypeScript runner +npm install -g tsx + +# 4. Start zero-build development +cd packages/htmldocs +tsx src/cli/index.ts dev --dir ../../apps/examples/documents +``` + +### What You Can Edit Without Building + +- ✅ **Template files** (`*.tsx` documents) - hot reload enabled +- ✅ **Next.js app** (`packages/htmldocs/src/app/*`) - hot reload enabled +- ✅ **CLI logic** (`packages/htmldocs/src/cli/*`) - restart to see changes +- ✅ **Styles** (CSS, Tailwind) - hot reload enabled + +### What Requires Building + +- ⚠️ **React components** (`packages/react/`) - run `pnpm build` after changes +- ⚠️ **Render engine** (`packages/render/`) - run `pnpm build` after changes + +### Development Commands + +```bash +# Start development with hot reload +tsx src/cli/index.ts dev --dir ../../apps/examples/documents + +# Build core packages when needed +pnpm build + +# Run tests +pnpm test + +# Format code +pnpm format +``` + +This workflow enables you to modify templates and see changes instantly in your browser, providing a smooth development experience similar to modern web frameworks. + ## Components htmldocs comes with a standard set of components to help you layout and style your documents. @@ -99,6 +172,68 @@ htmldocs also uses the [Paged.js library](https://pagedjs.org/) under the hood. |--------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| | Next.js | TypeScript | Turborepo | pnpm | +## Monorepo Architecture + +This project uses a monorepo structure with pnpm workspaces and Turbo for efficient development: + +``` +├── packages/ +│ ├── htmldocs/ # Main CLI and Next.js app +│ ├── react/ # React components (@htmldocs/react) +│ ├── render/ # PDF rendering engine (@htmldocs/render) +│ ├── eslint-config/ # Shared ESLint configuration +│ └── typescript-config/ # Shared TypeScript configuration +├── apps/ +│ ├── examples/ # Example templates and documents +│ └── docs/ # Documentation site +``` + +### Package Dependencies + +- `htmldocs` → depends on `@htmldocs/render` +- `examples` → depends on `htmldocs`, `@htmldocs/react`, `@htmldocs/render` +- All packages → share `@htmldocs/eslint-config` and `@htmldocs/typescript-config` + +The monorepo uses `workspace:*` protocol for internal dependencies, enabling seamless development across packages with automatic linking. + +## Contributing + +We welcome contributions! Here's how to get started: + +### Development Environment + +1. **Clone and setup**: + ```bash + git clone https://github.com/htmldocs-js/htmldocs.git + cd htmldocs + pnpm install + ``` + +2. **Start development**: + ```bash + ./dev.sh + ``` + +3. **Make changes** to templates in `apps/examples/documents/templates/` + +4. **See changes instantly** in your browser with hot reload + +### Common Tasks + +- **Add new templates**: Create `.tsx` files in `apps/examples/documents/templates/` +- **Modify components**: Edit `packages/react/components/` (requires `pnpm build`) +- **Update CLI**: Edit `packages/htmldocs/src/cli/` (restart dev server) +- **Fix rendering**: Edit `packages/render/src/` (requires `pnpm build`) + +### Testing + +```bash +pnpm test # Run all tests +pnpm test:coverage # Run tests with coverage +pnpm lint # Check code style +pnpm format # Format code +``` + ## License MIT License diff --git a/apps/examples/dist/Book/Book.schema.json b/apps/examples/dist/Book/Book.schema.json new file mode 100644 index 0000000..7ae757c --- /dev/null +++ b/apps/examples/dist/Book/Book.schema.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/ComponentProps", + "definitions": { + "ComponentProps": { + "type": "object", + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/apps/examples/documents/templates/Index.tsx b/apps/examples/documents/templates/Index.tsx new file mode 100644 index 0000000..9d20088 --- /dev/null +++ b/apps/examples/documents/templates/Index.tsx @@ -0,0 +1,201 @@ +// Import all available components from the htmldocs library +import { Document, Head, Page, Footer, MarginBox, Spacer } from '@htmldocs/react'; +import * as React from 'react'; +// Import CSS for Tailwind support +import "~/index.css"; + +// Main template component showcasing all htmldocs features +export default function Index() { + + return ( + + + Document Template + {/* + IMPORTANT FOR AI: + - Do NOT add Google Fonts links (may be blocked/slow loading) + - Do NOT add local font files that don't exist + - Use only system fonts and Tailwind defaults + - Keep Head section minimal for fast rendering + */} + + + {/* Page header in margin - shows on all pages */} + + Doc-001 | 2025 + + + {/* Page footer with numbering */} + + + + {/* Clean document header */} +
+

Document Title

+

Professional Document Template

+
+
+ + {/* Essential info section */} +
+
+
+

Document Details

+
+
Date: September 26, 2025
+
Reference: DOC-001
+
Status: Draft
+
+
+
+

Contact Information

+
+
Company Name
+
contact@company.com
+
(555) 123-4567
+
+
+
+
+ + {/* Main content area */} +
+

Executive Summary

+

+ This document template demonstrates clean, professional formatting with essential + components. It includes headers, footers, spacing controls, and multi-page support + while maintaining fast loading times and visual clarity. +

+ +

Key Features

+ + {/* Feature highlights in clean boxes */} +
+
+

Layout Control

+
    +
  • • A4 page sizing
  • +
  • • Automatic page breaks
  • +
  • • Margin management
  • +
+
+
+

Content Features

+
    +
  • • Headers and footers
  • +
  • • Page numbering
  • +
  • • Spacing control
  • +
+
+
+ + + + {/* Data presentation example */} +

Sample Data Table

+
+ + + + + + + + + + + + + + + + + + + + +
ItemDescriptionValue
Component AEssential feature100%
Component BOptional feature85%
+
+
+ + {/* Clean conclusion */} +
+

Summary

+

+ This template provides a solid foundation for professional documents with + clean formatting, essential features, and fast rendering. All components + use reliable system fonts and minimal external dependencies. +

+
+
+ + {/* Second page example */} + +
+

Additional Content

+ +
+

Multi-page Support

+

+ Content automatically flows to new pages. Headers and footers + appear consistently across all pages. +

+
+ + {/* Content sections */} +
+
+

Section One

+

+ Content for the first major section goes here. This demonstrates + how text flows naturally within the document structure. +

+
+ +
+

Section Two

+

+ Additional content sections can be added as needed. The template + maintains consistent formatting throughout. +

+
+ + + +
+

Lists and Formatting

+
+
+

Ordered List:

+
    +
  1. First item
  2. +
  3. Second item
  4. +
  5. Third item
  6. +
+
+
+

Bullet List:

+
    +
  • Key point one
  • +
  • Key point two
  • +
  • Key point three
  • +
+
+
+
+
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/apps/examples/documents/templates/Invoice.tsx b/apps/examples/documents/templates/Invoice.tsx index 21e2b6c..315e2d2 100644 --- a/apps/examples/documents/templates/Invoice.tsx +++ b/apps/examples/documents/templates/Invoice.tsx @@ -84,7 +84,7 @@ function Invoice({ billedTo, yourCompany, services }: InvoiceProps) { className="flex flex-row items-center justify-between" >
-
Invoice
+
🚀 开发中 Invoice

#AB2324-01

diff --git a/build-all.sh b/build-all.sh new file mode 100755 index 0000000..c1850bf --- /dev/null +++ b/build-all.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +# HTMLDocs 预编译脚本 +# 编译所有必要的包,供生产环境直接使用 + +set -e # 遇到错误时退出 + +# 获取脚本所在的绝对路径 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$SCRIPT_DIR" + +echo "🏗️ HTMLDocs 预编译模式" +echo "================================" +echo "📁 项目根目录: $PROJECT_ROOT" +echo + +# 确保在正确的目录 +if [[ ! -f "$PROJECT_ROOT/pnpm-workspace.yaml" ]]; then + echo "❌ 未找到 pnpm-workspace.yaml,请确保在项目根目录运行此脚本" + exit 1 +fi + +# 检查是否安装了依赖 +if [[ ! -d "$PROJECT_ROOT/node_modules" ]]; then + echo "📦 安装项目依赖..." + pnpm install + echo +fi + +# 定义关键路径 +PACKAGES_DIR="$PROJECT_ROOT/packages" +REACT_PKG_DIR="$PACKAGES_DIR/react" +RENDER_PKG_DIR="$PACKAGES_DIR/render" +HTMLDOCS_PKG_DIR="$PACKAGES_DIR/htmldocs" + +echo "🔧 开始编译所有包..." + +# 使用 turbo 进行并行构建(如果可用) +if command -v turbo &> /dev/null; then + echo "⚡ 使用 Turbo 进行并行构建..." + pnpm build +else + echo "📦 依次构建各个包..." + + # 构建 React 包 + echo " 🔨 构建 @htmldocs/react..." + cd "$REACT_PKG_DIR" + pnpm build + + # 构建 Render 包 + echo " 🔨 构建 @htmldocs/render..." + cd "$RENDER_PKG_DIR" + pnpm build + + # 构建 HTMLDocs 包 + echo " 🔨 构建 @htmldocs/htmldocs..." + cd "$HTMLDOCS_PKG_DIR" + pnpm build + + cd "$PROJECT_ROOT" +fi + +echo +echo "✅ 所有包编译完成!" +echo +echo "📋 编译产物位置:" +echo " 📦 @htmldocs/react: $REACT_PKG_DIR/dist/" +echo " 📦 @htmldocs/render: $RENDER_PKG_DIR/dist/" +echo " 📦 @htmldocs/htmldocs: $HTMLDOCS_PKG_DIR/dist/" +echo + +# 检查编译产物 +echo "🔍 验证编译产物..." +missing_builds=0 + +for pkg_dir in "$REACT_PKG_DIR" "$RENDER_PKG_DIR" "$HTMLDOCS_PKG_DIR"; do + pkg_name=$(basename "$pkg_dir") + if [[ ! -d "$pkg_dir/dist" ]]; then + echo "❌ 缺少编译产物: packages/$pkg_name/dist/" + ((missing_builds++)) + else + file_count=$(find "$pkg_dir/dist" -type f | wc -l) + echo "✅ packages/$pkg_name/dist/ ($file_count 个文件)" + fi +done + +if [[ $missing_builds -gt 0 ]]; then + echo + echo "❌ 编译未完全成功,请检查上述错误信息" + exit 1 +fi + +echo +echo "🎉 预编译完成!" +echo "💡 提示:" +echo " 1. 运行 'git add packages/*/dist/' 来添加编译产物到版本控制" +echo " 2. 运行 'git commit -m \"Add prebuilt packages\"' 提交编译产物" +echo " 3. 之后克隆项目可以直接使用 ./prod-dev.sh 快速启动" +echo \ No newline at end of file diff --git a/dev-workflow.js b/dev-workflow.js new file mode 100644 index 0000000..c5d9f9a --- /dev/null +++ b/dev-workflow.js @@ -0,0 +1,64 @@ +#!/usr/bin/env node + +/** + * HTMLDocs 零构建开发工作流程 + * + * 直接运行 TypeScript 源码,无需预先构建 + * 使用方法: + * node dev-workflow.js dev + * node dev-workflow.js dev --dir ./my-templates + */ + +import { spawn } from 'child_process'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// CLI 源码路径 +const cliSourcePath = path.join(__dirname, 'packages/htmldocs/src/cli/index.ts'); + +// 检查是否安装了 tsx +let useNodeLoader = true; +try { + const { execSync } = await import('child_process'); + execSync('tsx --version', { stdio: 'ignore' }); + useNodeLoader = false; +} catch (e) { + // tsx 未安装,使用 Node.js --loader +} + +// 构建参数 +const args = useNodeLoader + ? [ + '--loader', '@esbuild-kit/esm-loader', + cliSourcePath, + ...process.argv.slice(2) + ] + : [ + cliSourcePath, + ...process.argv.slice(2) + ]; + +const command = useNodeLoader ? 'node' : 'tsx'; + +// 设置开发环境变量 +const env = { + ...process.env, + NODE_ENV: 'development' +}; + +console.log('🚀 Starting HTMLDocs CLI in development mode...'); +console.log('📁 Running source:', cliSourcePath); +console.log('🔧 Command:', command, args.join(' ')); + +const child = spawn(command, args, { + stdio: 'inherit', + env, + cwd: path.join(__dirname, 'packages/htmldocs') +}); + +child.on('exit', (code) => { + process.exit(code || 0); +}); \ No newline at end of file diff --git a/dev.sh b/dev.sh new file mode 100755 index 0000000..84eee93 --- /dev/null +++ b/dev.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# HTMLDocs 零构建开发工作流程 +# 直接从源码运行,无需预先构建 + +set -e # 遇到错误时退出 + +# 获取脚本所在的绝对路径 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$SCRIPT_DIR" + +echo "🚀 HTMLDocs 零构建开发模式" +echo "================================" +echo "📁 项目根目录: $PROJECT_ROOT" +echo + +# 确保在正确的目录 +if [[ ! -f "$PROJECT_ROOT/pnpm-workspace.yaml" ]]; then + echo "❌ 未找到 pnpm-workspace.yaml,请确保在项目根目录运行此脚本" + exit 1 +fi + +# 定义关键路径 +PACKAGES_DIR="$PROJECT_ROOT/packages" +REACT_PKG_DIR="$PACKAGES_DIR/react" +RENDER_PKG_DIR="$PACKAGES_DIR/render" +HTMLDOCS_PKG_DIR="$PACKAGES_DIR/htmldocs" +EXAMPLES_DIR="$PROJECT_ROOT/apps/examples" +DOCUMENTS_DIR="$EXAMPLES_DIR/documents" + +# 验证关键目录存在 +for dir in "$PACKAGES_DIR" "$REACT_PKG_DIR" "$RENDER_PKG_DIR" "$HTMLDOCS_PKG_DIR" "$EXAMPLES_DIR" "$DOCUMENTS_DIR"; do + if [[ ! -d "$dir" ]]; then + echo "❌ 目录不存在: $dir" + exit 1 + fi +done + +# 确保安装了 tsx +if ! command -v tsx &> /dev/null; then + echo "📦 安装 tsx (TypeScript 运行器)..." + npm install -g tsx + echo +fi + +# 保存当前目录,用于后续恢复 +ORIGINAL_DIR="$(pwd)" + +# 错误处理函数 +cleanup() { + echo "🧹 清理并返回原始目录..." + cd "$ORIGINAL_DIR" +} + +# 设置退出时的清理 +trap cleanup EXIT + +# 构建依赖的包(仅一次性需要) +echo "🔧 检查并构建依赖包..." + +# 构建 React 包 +cd "$REACT_PKG_DIR" +if [[ ! -d dist ]]; then + echo " 📦 构建 @htmldocs/react..." + pnpm build +else + echo " ✅ @htmldocs/react 已构建" +fi + +# 构建 Render 包 +cd "$RENDER_PKG_DIR" +if [[ ! -d dist ]]; then + echo " 📦 构建 @htmldocs/render..." + pnpm build +else + echo " ✅ @htmldocs/render 已构建" +fi + +echo + +echo "🌟 启动零构建开发服务器..." +echo " 📁 模板目录: $DOCUMENTS_DIR" +echo " 🌐 预览地址: http://localhost:3000 (或下一个可用端口)" +echo " 🔥 热重载: 模板文件修改后自动刷新" +echo " 📝 编辑文件: $DOCUMENTS_DIR/templates/*.tsx" +echo +echo "按 Ctrl+C 停止服务器" +echo "================================" +echo + +# 切换到 htmldocs 包目录以确保路径解析正确 +cd "$HTMLDOCS_PKG_DIR" + +# 直接运行 TypeScript 源码,指向正确的文档目录 +tsx src/cli/index.ts dev --dir "$DOCUMENTS_DIR" \ No newline at end of file diff --git a/llms.txt b/llms.txt new file mode 100644 index 0000000..178b4f2 --- /dev/null +++ b/llms.txt @@ -0,0 +1,32 @@ +# Docs + +> HTMLDocs is a comprehensive documentation platform that helps developers and teams create, manage, and publish high-quality documentation for their products and services. With a focus on ease of use, customization, and seamless integration, HTMLDocs empowers organizations to deliver engaging and accessible documentation that enhances the user experience and supports their customers throughout the product lifecycle. + +## API & Developer +- [Authorization API](https://docs.htmldocs.com/api-reference/authorization): Learn how to authenticate and authorize access to the HTMLDocs API for your applications. +- [Generate Document API](https://docs.htmldocs.com/api-reference/generate-document): Discover how to use the HTMLDocs API to programmatically generate and customize documents for your users. +- [Generate HTML API](https://docs.htmldocs.com/api-reference/generate-html): Explore the HTMLDocs API for generating and customizing HTML content for your documentation. +- [Command-Line Interface (CLI)](https://docs.htmldocs.com/cli): Learn how to use the HTMLDocs CLI to streamline your documentation workflow and automate common tasks. + +## Documentation +- [Getting Started](https://docs.htmldocs.com/getting-started): A comprehensive guide to setting up and using HTMLDocs for your documentation needs. +- [Introduction](https://docs.htmldocs.com/introduction): Explore the key features and capabilities of the HTMLDocs platform and how it can benefit your organization. +- [Using Custom Fonts](https://docs.htmldocs.com/usage/custom-fonts): Learn how to integrate and use custom fonts in your HTMLDocs-powered documentation. +- [Publishing to the Cloud](https://docs.htmldocs.com/usage/publishing-to-the-cloud): Discover how to seamlessly publish your HTMLDocs documentation to the cloud for easy access and distribution. +- [Working with Static Content](https://docs.htmldocs.com/usage/static-content): Guidance on incorporating and managing static content within your HTMLDocs documentation. +- [Integrating Tailwind CSS](https://docs.htmldocs.com/usage/tailwind): Learn how to leverage the Tailwind CSS framework to customize the styling and appearance of your HTMLDocs documentation. +- [Using Template Variables](https://docs.htmldocs.com/usage/template-variables): Explore the available template variables and how to use them to dynamically generate content in your HTMLDocs documentation. + +## Components +- [Document Component](https://docs.htmldocs.com/components/document): Understand the structure and configuration of the core Document component in HTMLDocs. +- [Footer Component](https://docs.htmldocs.com/components/footer): Learn how to customize and configure the Footer component in your HTMLDocs documentation. +- [Head Component](https://docs.htmldocs.com/components/head): Explore the Head component and how to manage the metadata and settings for your HTMLDocs documentation. +- [Margin Box Component](https://docs.htmldocs.com/components/margin-box): Discover the Margin Box component and how to use it to control the spacing and layout of your HTMLDocs documentation. +- [Page Component](https://docs.htmldocs.com/components/page): Learn about the Page component and how to structure and organize your HTMLDocs documentation. +- [Spacer Component](https://docs.htmldocs.com/components/spacer): Understand the Spacer component and how to use it to manage the spacing between elements in your HTMLDocs documentation. + +## Integrations +- [Resend Integration](https://docs.htmldocs.com/integrations/resend): Discover how to integrate HTMLDocs with the Resend email delivery platform to enhance your documentation workflow. + +## Comparison +- [HTMLDocs Comparison](https://docs.htmldocs.com/comparison): Explore how HTMLDocs compares to other documentation platforms and solutions in the market. \ No newline at end of file diff --git a/package.json b/package.json index 34074e1..3ea3b63 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "scripts": { "build": "turbo run build --filter=./packages/* --filter=!htmldocs-starter", "dev": "turbo dev", + "devsh": "./dev.sh", + "prod":"./prod-dev.sh", "lint": "turbo lint", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "version": "changeset version && pnpm install --no-frozen-lockfile", diff --git a/packages/htmldocs/dist/Book/Book.schema.json b/packages/htmldocs/dist/Book/Book.schema.json new file mode 100644 index 0000000..7ae757c --- /dev/null +++ b/packages/htmldocs/dist/Book/Book.schema.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/ComponentProps", + "definitions": { + "ComponentProps": { + "type": "object", + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/packages/htmldocs/dist/Index/Index.schema.json b/packages/htmldocs/dist/Index/Index.schema.json new file mode 100644 index 0000000..7ae757c --- /dev/null +++ b/packages/htmldocs/dist/Index/Index.schema.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/ComponentProps", + "definitions": { + "ComponentProps": { + "type": "object", + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/packages/htmldocs/dist/Receipt/Receipt.schema.json b/packages/htmldocs/dist/Receipt/Receipt.schema.json new file mode 100644 index 0000000..5069099 --- /dev/null +++ b/packages/htmldocs/dist/Receipt/Receipt.schema.json @@ -0,0 +1,102 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/ComponentProps", + "definitions": { + "ComponentProps": { + "type": "object", + "properties": { + "orderNumber": { + "type": "string" + }, + "orderDate": { + "type": "string" + }, + "orderTotal": { + "type": "string" + }, + "customerName": { + "type": "string" + }, + "billingAddress": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "street": { + "type": "string" + }, + "city": { + "type": "string" + }, + "state": { + "type": "string" + }, + "zip": { + "type": "string" + }, + "country": { + "type": "string" + } + }, + "required": [ + "name", + "street", + "city", + "state", + "zip", + "country" + ], + "additionalProperties": false + }, + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "quantity": { + "type": "number" + }, + "price": { + "type": "string" + }, + "discountedPrice": { + "type": [ + "string", + "null" + ] + }, + "image": { + "type": "string" + } + }, + "required": [ + "name", + "description", + "quantity", + "price", + "discountedPrice", + "image" + ], + "additionalProperties": false + } + } + }, + "required": [ + "orderNumber", + "orderDate", + "orderTotal", + "customerName", + "billingAddress", + "items" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/packages/htmldocs/dist/cli/index.d.mts b/packages/htmldocs/dist/cli/index.d.mts new file mode 100644 index 0000000..223e65e --- /dev/null +++ b/packages/htmldocs/dist/cli/index.d.mts @@ -0,0 +1,2 @@ + +export { } diff --git a/packages/htmldocs/dist/cli/index.mjs b/packages/htmldocs/dist/cli/index.mjs new file mode 100755 index 0000000..e3664b8 --- /dev/null +++ b/packages/htmldocs/dist/cli/index.mjs @@ -0,0 +1,2953 @@ +#!/usr/bin/env node +function _array_like_to_array(arr, len) { + if (len == null || len > arr.length) len = arr.length; + for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i]; + return arr2; +} +function _array_with_holes(arr) { + if (Array.isArray(arr)) return arr; +} +function _array_without_holes(arr) { + if (Array.isArray(arr)) return _array_like_to_array(arr); +} +function _async_iterator(iterable) { + var method, async, sync, retry = 2; + for("undefined" != typeof Symbol && (async = Symbol.asyncIterator, sync = Symbol.iterator); retry--;){ + if (async && null != (method = iterable[async])) return method.call(iterable); + if (sync && null != (method = iterable[sync])) return new AsyncFromSyncIterator(method.call(iterable)); + async = "@@asyncIterator", sync = "@@iterator"; + } + throw new TypeError("Object is not async iterable"); +} +function AsyncFromSyncIterator(s) { + function AsyncFromSyncIteratorContinuation(r) { + if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); + var done = r.done; + return Promise.resolve(r.value).then(function(value) { + return { + value: value, + done: done + }; + }); + } + return AsyncFromSyncIterator = function(s) { + this.s = s, this.n = s.next; + }, AsyncFromSyncIterator.prototype = { + s: null, + n: null, + next: function() { + return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); + }, + return: function(value) { + var ret = this.s.return; + return void 0 === ret ? Promise.resolve({ + value: value, + done: !0 + }) : AsyncFromSyncIteratorContinuation(ret.apply(this.s, arguments)); + }, + throw: function(value) { + var thr = this.s.return; + return void 0 === thr ? Promise.reject(value) : AsyncFromSyncIteratorContinuation(thr.apply(this.s, arguments)); + } + }, new AsyncFromSyncIterator(s); +} +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} +function _async_to_generator(fn) { + return function() { + var self = this, args = arguments; + return new Promise(function(resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + _next(undefined); + }); + }; +} +function _class_call_check(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +} +function _defineProperties(target, props) { + for(var i = 0; i < props.length; i++){ + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } +} +function _create_class(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; +} +function _define_property(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} +function _iterable_to_array(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); +} +function _iterable_to_array_limit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; + var _s, _e; + try { + for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){ + _arr.push(_s.value); + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally{ + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally{ + if (_d) throw _e; + } + } + return _arr; +} +function _non_iterable_rest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} +function _non_iterable_spread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} +function _object_spread(target) { + for(var i = 1; i < arguments.length; i++){ + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + if (typeof Object.getOwnPropertySymbols === "function") { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + ownKeys.forEach(function(key) { + _define_property(target, key, source[key]); + }); + } + return target; +} +function _sliced_to_array(arr, i) { + return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest(); +} +function _to_consumable_array(arr) { + return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread(); +} +function _unsupported_iterable_to_array(o, minLen) { + if (!o) return; + if (typeof o === "string") return _array_like_to_array(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(n); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen); +} +function _ts_generator(thisArg, body) { + var f, y, t, g, _ = { + label: 0, + sent: function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([ + n, + v + ]); + }; + } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while(_)try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [ + op[0] & 2, + t.value + ]; + switch(op[0]){ + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { + value: op[1], + done: false + }; + case 5: + _.label++; + y = op[1]; + op = [ + 0 + ]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [ + 6, + e + ]; + y = 0; + } finally{ + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } +} +// src/cli/index.ts +import { program } from "commander"; +// package.json +var package_default = { + name: "htmldocs", + keywords: [ + "pdf", + "document", + "generator", + "react", + "typescript", + "tailwind", + "jsx", + "template", + "invoice", + "resume", + "report", + "contract", + "pdf-generator", + "pdf-template", + "pdf-document", + "pdf-editor", + "pdf-creator", + "latex", + "pagedjs", + "react-pdf", + "typst", + "invoice-generator", + "resume-generator", + "report-generator", + "contract-generator" + ], + version: "0.2.30", + homepage: "https://htmldocs.com", + repository: { + type: "git", + url: "https://github.com/htmldocs-js/htmldocs" + }, + bin: { + htmldocs: "./dist/cli/index.mjs" + }, + scripts: { + init: "npx playwright install", + build: "node build-preview-server.mjs && pnpm build-cli", + "build:dev": "node build-preview-server.mjs && pnpm build-cli:dev", + "build-cli": "API_URL=https://htmldocs.com tsup-node", + "build-cli:dev": "API_URL=http://localhost:3000 tsup-node && pnpm link --global", + dev: "next dev", + start: "next start", + lint: "next lint", + tsc: "tsc", + test: "vitest", + "test:coverage": "vitest run --coverage" + }, + dependencies: { + "@babel/core": "^7.24.6", + "@babel/parser": "^7.24.5", + "@babel/preset-typescript": "^7.24.6", + "@htmldocs/render": "workspace:*", + "@next/bundle-analyzer": "^15.1.6", + "@phosphor-icons/react": "^2.1.5", + "@radix-ui/react-collapsible": "^1.0.3", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.1.0", + "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-toggle-group": "^1.0.4", + "@radix-ui/react-tooltip": "^1.0.7", + "@tailwindcss/typography": "0.5.9", + "adm-zip": "^0.5.14", + autoprefixer: "^10.4.19", + chalk: "^4.1.2", + chokidar: "^3.6.0", + "class-variance-authority": "^0.7.0", + clsx: "^2.1.1", + commander: "^12.1.0", + cva: "1.0.0-beta.1", + debounce: "^2.0.0", + dotenv: "^16.4.7", + esbuild: "^0.21.3", + "esbuild-plugin-tsc": "^0.4.0", + "esbuild-style-plugin": "^1.6.3", + "form-data": "^4.0.0", + "framer-motion": "^11.2.6", + "fs-extra": "^11.2.0", + inquirer: "^11.0.2", + lodash: "^4.17.21", + "log-symbols": "^4.1.0", + "mime-types": "^2.1.35", + next: "14.2.3", + "next-themes": "^0.3.0", + "node-fetch": "^2.7.0", + onetime: "^7.0.0", + open: "^8.4.2", + ora: "^5.4.1", + pino: "^9.3.2", + playwright: "^1.44.1", + postcss: "^8.4.38", + react: "^18.2.0", + "react-docgen": "^7.0.3", + "react-dom": "^18.2.0", + "socket.io": "^4.7.5", + "socket.io-client": "^4.7.5", + sonner: "^1.4.41", + "source-map-js": "^1.2.0", + "tailwind-merge": "^2.3.0", + tailwindcss: "^3.4.3", + "tailwindcss-animate": "^1.0.7", + "ts-json-schema-generator": "^2.2.0", + zod: "^3.23.8" + }, + devDependencies: { + "@swc/core": "^1.5.7", + "@types/babel__core": "^7.20.5", + "@types/json-schema": "^7.0.15", + "@types/mime-types": "^2.1.4", + "@types/node": "^20", + "@types/react": "^18.2.61", + "@types/react-dom": "^18.2.19", + tsup: "^8.0.2", + typescript: "^5" + } +}; +// src/cli/commands/dev.ts +import fs3 from "node:fs"; +import path6 from "node:path"; +// src/cli/utils/preview/start-dev-server.ts +import path2 from "node:path"; +import http from "node:http"; +import url from "node:url"; +import next from "next"; +import ora from "ora"; +import logSymbols from "log-symbols"; +import chalk from "chalk"; +// src/cli/utils/close-ora-on-sigint.ts +var closeOraOnSIGINT = function(spinner) { + process.on("SIGINT", function() { + spinner.stop(); + }); +}; +// src/cli/utils/preview/serve-static-file.ts +import path from "node:path"; +import { promises as fs } from "node:fs"; +import { lookup } from "mime-types"; +var serveStaticFile = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(res, parsedUrl, staticDirRelativePath) { + var staticBaseDir, pathname, ext, fileAbsolutePath, fileHandle, fileData, exception; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + staticBaseDir = path.join(process.cwd(), staticDirRelativePath); + pathname = parsedUrl.pathname; + ext = path.parse(pathname).ext; + fileAbsolutePath = path.join(staticBaseDir, pathname); + return [ + 4, + fs.open(fileAbsolutePath, "r") + ]; + case 1: + fileHandle = _state.sent(); + _state.label = 2; + case 2: + _state.trys.push([ + 2, + 4, + 5, + 6 + ]); + return [ + 4, + fs.readFile(fileHandle) + ]; + case 3: + fileData = _state.sent(); + res.setHeader("Content-type", lookup(ext) || "text/plain"); + res.end(fileData); + return [ + 3, + 6 + ]; + case 4: + exception = _state.sent(); + console.error("Could not read file at ".concat(fileAbsolutePath, " to be served, here's the exception:"), exception); + res.statusCode = 500; + res.end("Could not read file to be served! Check your terminal for more information."); + return [ + 3, + 6 + ]; + case 5: + fileHandle.close(); + return [ + 7 + ]; + case 6: + return [ + 2 + ]; + } + }); + }); + return function serveStaticFile(res, parsedUrl, staticDirRelativePath) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/utils/preview/start-dev-server.ts +import { fileURLToPath } from "url"; +import { dirname } from "path"; +var __filename = fileURLToPath(import.meta.url); +var __dirname = dirname(__filename); +var devServer; +var safeAsyncServerListen = function(server, port) { + return new Promise(function(resolve) { + server.listen(port, function() { + resolve({ + portAlreadyInUse: false + }); + }); + server.on("error", function(e) { + if (e.code === "EADDRINUSE") { + resolve({ + portAlreadyInUse: true + }); + } + }); + }); +}; +var isRunningBuilt = __filename.endsWith(path2.join("cli", "index.mjs")); +var cliPackageLocation = isRunningBuilt ? path2.resolve(__dirname, "../") : path2.resolve(__dirname, "../../../.."); +var previewServerLocation = isRunningBuilt ? path2.resolve(__dirname, "../preview") : path2.resolve(__dirname, "../../../.."); +var startDevServer = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(documentsDirRelativePath2, staticBaseDirRelativePath, port) { + var portAlreadyInUse, nextPortToTry, spinner, timeBeforeNextReady, app, isNextReady, nextReadyPromise, nextHandleRequest, secondsToNextReady; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + devServer = http.createServer(function(req, res) { + if (!req.url) { + res.end(404); + return; + } + var parsedUrl = url.parse(req.url, true); + res.setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store"); + res.setHeader("Pragma", "no-cache"); + res.setHeader("Expires", "-1"); + try { + if (parsedUrl.path && parsedUrl.path.includes("static/") && !parsedUrl.path.includes("_next/static/")) { + void serveStaticFile(res, parsedUrl, staticBaseDirRelativePath); + } else if (!isNextReady) { + void nextReadyPromise.then(function() { + return nextHandleRequest === null || nextHandleRequest === void 0 ? void 0 : nextHandleRequest(req, res, parsedUrl); + }); + } else { + void (nextHandleRequest === null || nextHandleRequest === void 0 ? void 0 : nextHandleRequest(req, res, parsedUrl)); + } + } catch (e) { + console.error("caught error", e); + res.writeHead(500); + res.end(); + } + }); + return [ + 4, + safeAsyncServerListen(devServer, port) + ]; + case 1: + portAlreadyInUse = _state.sent().portAlreadyInUse; + if (!portAlreadyInUse) { + console.log(chalk.greenBright(" htmldocs ".concat(package_default.version))); + console.log(" Running preview at: http://localhost:".concat(port, "\n")); + } else { + nextPortToTry = port + 1; + console.warn(" ".concat(logSymbols.warning, " Port ").concat(port, " is already in use, trying ").concat(nextPortToTry)); + return [ + 2, + startDevServer(documentsDirRelativePath2, staticBaseDirRelativePath, nextPortToTry) + ]; + } + devServer.on("close", /*#__PURE__*/ _async_to_generator(function() { + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + return [ + 4, + app.close() + ]; + case 1: + _state.sent(); + return [ + 2 + ]; + } + }); + })); + devServer.on("error", function(e) { + console.error(" ".concat(logSymbols.error, " preview server error: "), JSON.stringify(e)); + process.exit(1); + }); + spinner = ora({ + text: "Getting htmldocs preview server ready...\n", + prefixText: " " + }).start(); + closeOraOnSIGINT(spinner); + timeBeforeNextReady = performance.now(); + app = next({ + // passing in env here does not get the environment variables there + dev: !isRunningBuilt, + hostname: "localhost", + port: port, + dir: previewServerLocation + }); + isNextReady = false; + nextReadyPromise = app.prepare(); + return [ + 4, + nextReadyPromise + ]; + case 2: + _state.sent(); + isNextReady = true; + nextHandleRequest = app.getRequestHandler(); + secondsToNextReady = ((performance.now() - timeBeforeNextReady) / 1e3).toFixed(1); + spinner.stopAndPersist({ + text: "Ready in ".concat(secondsToNextReady, "s\n"), + symbol: logSymbols.success + }); + return [ + 2, + devServer + ]; + } + }); + }); + return function startDevServer(documentsDirRelativePath2, staticBaseDirRelativePath, port) { + return _ref.apply(this, arguments); + }; +}(); +var makeExitHandler = function(options) { + return function(_codeOrSignal) { + if (typeof devServer !== "undefined") { + console.log("\nshutting down dev server"); + devServer.close(); + devServer = void 0; + } + if (options === null || options === void 0 ? void 0 : options.shouldKillProcess) { + process.exit(options.killWithErrorCode ? 1 : 0); + } + }; +}; +process.on("exit", makeExitHandler()); +process.on("SIGINT", makeExitHandler({ + shouldKillProcess: true, + killWithErrorCode: false +})); +process.on("SIGUSR1", makeExitHandler({ + shouldKillProcess: true, + killWithErrorCode: false +})); +process.on("SIGUSR2", makeExitHandler({ + shouldKillProcess: true, + killWithErrorCode: false +})); +// src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts +import path4 from "node:path"; +import { watch } from "chokidar"; +import debounce from "debounce"; +import { Server as SocketServer } from "socket.io"; +// src/cli/utils/preview/hot-reloading/create-dependency-graph.ts +import path3 from "node:path"; +import { existsSync, promises as fs2, statSync } from "node:fs"; +// src/cli/utils/preview/hot-reloading/get-imported-modules.ts +import { traverse } from "@babel/core"; +import { parse } from "@babel/parser"; +var getImportedModules = function(contents) { + var importedPaths = []; + var parsedContents = parse(contents, { + sourceType: "unambiguous", + strictMode: false, + errorRecovery: true, + plugins: [ + "jsx", + "typescript" + ] + }); + traverse(parsedContents, { + ImportDeclaration: function ImportDeclaration(param) { + var node = param.node; + importedPaths.push(node.source.value); + }, + ExportAllDeclaration: function ExportAllDeclaration(param) { + var node = param.node; + importedPaths.push(node.source.value); + }, + ExportNamedDeclaration: function ExportNamedDeclaration(param) { + var node = param.node; + if (node.source) { + importedPaths.push(node.source.value); + } + }, + CallExpression: function CallExpression(param) { + var node = param.node; + if ("name" in node.callee && node.callee.name === "require") { + if (node.arguments.length === 1) { + var importPathNode = node.arguments[0]; + if (importPathNode.type === "StringLiteral") { + importedPaths.push(importPathNode.value); + } + } + } + } + }); + return importedPaths; +}; +// src/cli/utils/preview/hot-reloading/create-dependency-graph.ts +var readAllFilesInsideDirectory = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(directory) { + var allFilePaths, topLevelDirents, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, dirent, pathToDirent, _, err; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + allFilePaths = []; + return [ + 4, + fs2.readdir(directory, { + withFileTypes: true + }) + ]; + case 1: + topLevelDirents = _state.sent(); + _iteratorAbruptCompletion = false, _didIteratorError = false; + _state.label = 2; + case 2: + _state.trys.push([ + 2, + 9, + 10, + 15 + ]); + _iterator = _async_iterator(topLevelDirents); + _state.label = 3; + case 3: + return [ + 4, + _iterator.next() + ]; + case 4: + if (!(_iteratorAbruptCompletion = !(_step = _state.sent()).done)) return [ + 3, + 8 + ]; + _value = _step.value; + dirent = _value; + pathToDirent = path3.join(directory, dirent.name); + if (!dirent.isDirectory()) return [ + 3, + 6 + ]; + _ = allFilePaths.concat; + return [ + 4, + readAllFilesInsideDirectory(pathToDirent) + ]; + case 5: + allFilePaths = _.apply(allFilePaths, [ + _state.sent() + ]); + return [ + 3, + 7 + ]; + case 6: + allFilePaths.push(pathToDirent); + _state.label = 7; + case 7: + _iteratorAbruptCompletion = false; + return [ + 3, + 3 + ]; + case 8: + return [ + 3, + 15 + ]; + case 9: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 15 + ]; + case 10: + _state.trys.push([ + 10, + , + 13, + 14 + ]); + if (!(_iteratorAbruptCompletion && _iterator.return != null)) return [ + 3, + 12 + ]; + return [ + 4, + _iterator.return() + ]; + case 11: + _state.sent(); + _state.label = 12; + case 12: + return [ + 3, + 14 + ]; + case 13: + if (_didIteratorError) { + throw _iteratorError; + } + return [ + 7 + ]; + case 14: + return [ + 7 + ]; + case 15: + return [ + 2, + allFilePaths + ]; + } + }); + }); + return function readAllFilesInsideDirectory(directory) { + return _ref.apply(this, arguments); + }; +}(); +var isJavascriptModule = function(filePath) { + var extensionName = path3.extname(filePath); + return [ + ".js", + ".ts", + ".jsx", + ".tsx", + ".mjs", + ".cjs" + ].includes(extensionName); +}; +var checkFileExtensionsUntilItExists = function(pathWithoutExtension) { + if (existsSync("".concat(pathWithoutExtension, ".ts"))) { + return "".concat(pathWithoutExtension, ".ts"); + } else if (existsSync("".concat(pathWithoutExtension, ".tsx"))) { + return "".concat(pathWithoutExtension, ".tsx"); + } else if (existsSync("".concat(pathWithoutExtension, ".js"))) { + return "".concat(pathWithoutExtension, ".js"); + } else if (existsSync("".concat(pathWithoutExtension, ".jsx"))) { + return "".concat(pathWithoutExtension, ".jsx"); + } else if (existsSync("".concat(pathWithoutExtension, ".mjs"))) { + return "".concat(pathWithoutExtension, ".mjs"); + } else if (existsSync("".concat(pathWithoutExtension, ".cjs"))) { + return "".concat(pathWithoutExtension, ".cjs"); + } +}; +var createDependencyGraph = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(directory) { + var filePaths, modulePaths, graph, getDependencyPaths, updateModuleDependenciesInGraph, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, filePath, err, removeModuleFromGraph; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + return [ + 4, + readAllFilesInsideDirectory(directory) + ]; + case 1: + filePaths = _state.sent(); + modulePaths = filePaths.filter(isJavascriptModule); + graph = Object.fromEntries(modulePaths.map(function(path13) { + return [ + path13, + { + path: path13, + dependencyPaths: [], + dependentPaths: [], + moduleDependencies: [] + } + ]; + })); + getDependencyPaths = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(filePath) { + var contents, importedPaths, importedPathsRelativeToDirectory, moduleDependencies, nonNodeModuleImportPathsRelativeToDirectory; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + return [ + 4, + fs2.readFile(filePath, "utf8") + ]; + case 1: + contents = _state.sent(); + importedPaths = getImportedModules(contents); + importedPathsRelativeToDirectory = importedPaths.map(function(dependencyPath) { + var isModulePath = !dependencyPath.startsWith("."); + if (!isModulePath && !path3.isAbsolute(dependencyPath)) { + var pathToDependencyFromDirectory = path3.resolve(/* + path.resolve resolves paths differently from what imports on javascript do. + + So if we wouldn't do this, for an email at "/path/to/email.tsx" with a dependecy path of "./other-email" + would end up going into /path/to/email.tsx/other-email instead of /path/to/other-email which is the + one the import is meant to go to + */ path3.dirname(filePath), dependencyPath); + var isDirectory = false; + try { + isDirectory = statSync(pathToDependencyFromDirectory).isDirectory(); + } catch (_) {} + if (isDirectory) { + var pathToSubDirectory = pathToDependencyFromDirectory; + var pathWithExtension = checkFileExtensionsUntilItExists("".concat(pathToSubDirectory, "/index")); + if (pathWithExtension) { + pathToDependencyFromDirectory = pathWithExtension; + } else if (isRunningBuilt) { + console.warn("Could not find index file for directory at ".concat(pathToDependencyFromDirectory, ". This is probably going to cause issues with both hot reloading and your code.")); + } + } + if (!isJavascriptModule(pathToDependencyFromDirectory)) { + var pathWithExtension1 = checkFileExtensionsUntilItExists(pathToDependencyFromDirectory); + if (pathWithExtension1) { + pathToDependencyFromDirectory = pathWithExtension1; + } else if (isRunningBuilt) { + console.warn("Could not determine the file extension for the file at ".concat(pathWithExtension1)); + } + } + return pathToDependencyFromDirectory; + } else { + return dependencyPath; + } + }); + moduleDependencies = importedPathsRelativeToDirectory.filter(function(dependencyPath) { + return !dependencyPath.startsWith(".") && !path3.isAbsolute(dependencyPath); + }); + nonNodeModuleImportPathsRelativeToDirectory = importedPathsRelativeToDirectory.filter(function(dependencyPath) { + return dependencyPath.startsWith(".") || path3.isAbsolute(dependencyPath); + }); + return [ + 2, + { + dependencyPaths: nonNodeModuleImportPathsRelativeToDirectory, + moduleDependencies: moduleDependencies + } + ]; + } + }); + }); + return function getDependencyPaths(filePath) { + return _ref.apply(this, arguments); + }; + }(); + updateModuleDependenciesInGraph = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(moduleFilePath) { + var _graph_moduleFilePath, module, _ref, moduleDependencies, newDependencyPaths, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, dependencyPath, dependencyModule, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, dependencyPath1, dependencyModule1; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + module = (_graph_moduleFilePath = graph[moduleFilePath]) !== null && _graph_moduleFilePath !== void 0 ? _graph_moduleFilePath : { + path: moduleFilePath, + dependencyPaths: [], + dependentPaths: [], + moduleDependencies: [] + }; + return [ + 4, + getDependencyPaths(moduleFilePath) + ]; + case 1: + _ref = _state.sent(), moduleDependencies = _ref.moduleDependencies, newDependencyPaths = _ref.dependencyPaths; + module.moduleDependencies = moduleDependencies; + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + try { + for(_iterator = module.dependencyPaths[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ + dependencyPath = _step.value; + if (newDependencyPaths.includes(dependencyPath)) continue; + dependencyModule = graph[dependencyPath]; + if (dependencyModule !== void 0) { + dependencyModule.dependentPaths = dependencyModule.dependentPaths.filter(function(dependentPath) { + return dependentPath !== moduleFilePath; + }); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally{ + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + } + module.dependencyPaths = newDependencyPaths; + _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined; + try { + for(_iterator1 = newDependencyPaths[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){ + dependencyPath1 = _step1.value; + dependencyModule1 = graph[dependencyPath1]; + if (dependencyModule1 !== void 0 && !dependencyModule1.dependentPaths.includes(moduleFilePath)) { + dependencyModule1.dependentPaths.push(moduleFilePath); + } else { + graph[dependencyPath1] = { + path: dependencyPath1, + moduleDependencies: [], + dependencyPaths: [], + dependentPaths: [ + moduleFilePath + ] + }; + } + } + } catch (err) { + _didIteratorError1 = true; + _iteratorError1 = err; + } finally{ + try { + if (!_iteratorNormalCompletion1 && _iterator1.return != null) { + _iterator1.return(); + } + } finally{ + if (_didIteratorError1) { + throw _iteratorError1; + } + } + } + graph[moduleFilePath] = module; + return [ + 2 + ]; + } + }); + }); + return function updateModuleDependenciesInGraph(moduleFilePath) { + return _ref.apply(this, arguments); + }; + }(); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + _state.label = 2; + case 2: + _state.trys.push([ + 2, + 7, + 8, + 9 + ]); + _iterator = modulePaths[Symbol.iterator](); + _state.label = 3; + case 3: + if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [ + 3, + 6 + ]; + filePath = _step.value; + return [ + 4, + updateModuleDependenciesInGraph(filePath) + ]; + case 4: + _state.sent(); + _state.label = 5; + case 5: + _iteratorNormalCompletion = true; + return [ + 3, + 3 + ]; + case 6: + return [ + 3, + 9 + ]; + case 7: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 9 + ]; + case 8: + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + return [ + 7 + ]; + case 9: + removeModuleFromGraph = function(filePath) { + var module = graph[filePath]; + if (module) { + var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + try { + for(var _iterator = module.dependencyPaths[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ + var dependencyPath = _step.value; + if (graph[dependencyPath]) { + graph[dependencyPath].dependentPaths = graph[dependencyPath].dependentPaths.filter(function(dependentPath) { + return dependentPath !== filePath; + }); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally{ + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + } + delete graph[filePath]; + } + }; + return [ + 2, + [ + graph, + /*#__PURE__*/ function() { + var _ref = /** + * @param pathToModified - A path relative to the previosuly provided {@link directory}. + */ _async_to_generator(function(event, pathToModified) { + var filesInsideAddedDirectory, modulesInsideAddedDirectory, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, filePath, err, filesInsideDeletedDirectory, modulesInsideDeletedDirectory, _iteratorAbruptCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _value1, filePath1, err1; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + switch(event){ + case "change": + return [ + 3, + 1 + ]; + case "add": + return [ + 3, + 4 + ]; + case "addDir": + return [ + 3, + 7 + ]; + case "unlink": + return [ + 3, + 22 + ]; + case "unlinkDir": + return [ + 3, + 23 + ]; + } + return [ + 3, + 37 + ]; + case 1: + if (!isJavascriptModule(pathToModified)) return [ + 3, + 3 + ]; + return [ + 4, + updateModuleDependenciesInGraph(pathToModified) + ]; + case 2: + _state.sent(); + _state.label = 3; + case 3: + return [ + 3, + 37 + ]; + case 4: + if (!isJavascriptModule(pathToModified)) return [ + 3, + 6 + ]; + return [ + 4, + updateModuleDependenciesInGraph(pathToModified) + ]; + case 5: + _state.sent(); + _state.label = 6; + case 6: + return [ + 3, + 37 + ]; + case 7: + return [ + 4, + readAllFilesInsideDirectory(pathToModified) + ]; + case 8: + filesInsideAddedDirectory = _state.sent(); + modulesInsideAddedDirectory = filesInsideAddedDirectory.filter(isJavascriptModule); + _iteratorAbruptCompletion = false, _didIteratorError = false; + _state.label = 9; + case 9: + _state.trys.push([ + 9, + 15, + 16, + 21 + ]); + _iterator = _async_iterator(modulesInsideAddedDirectory); + _state.label = 10; + case 10: + return [ + 4, + _iterator.next() + ]; + case 11: + if (!(_iteratorAbruptCompletion = !(_step = _state.sent()).done)) return [ + 3, + 14 + ]; + _value = _step.value; + filePath = _value; + return [ + 4, + updateModuleDependenciesInGraph(filePath) + ]; + case 12: + _state.sent(); + _state.label = 13; + case 13: + _iteratorAbruptCompletion = false; + return [ + 3, + 10 + ]; + case 14: + return [ + 3, + 21 + ]; + case 15: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 21 + ]; + case 16: + _state.trys.push([ + 16, + , + 19, + 20 + ]); + if (!(_iteratorAbruptCompletion && _iterator.return != null)) return [ + 3, + 18 + ]; + return [ + 4, + _iterator.return() + ]; + case 17: + _state.sent(); + _state.label = 18; + case 18: + return [ + 3, + 20 + ]; + case 19: + if (_didIteratorError) { + throw _iteratorError; + } + return [ + 7 + ]; + case 20: + return [ + 7 + ]; + case 21: + return [ + 3, + 37 + ]; + case 22: + if (isJavascriptModule(pathToModified)) { + removeModuleFromGraph(pathToModified); + } + return [ + 3, + 37 + ]; + case 23: + return [ + 4, + readAllFilesInsideDirectory(pathToModified) + ]; + case 24: + filesInsideDeletedDirectory = _state.sent(); + modulesInsideDeletedDirectory = filesInsideDeletedDirectory.filter(isJavascriptModule); + _iteratorAbruptCompletion1 = false, _didIteratorError1 = false; + _state.label = 25; + case 25: + _state.trys.push([ + 25, + 30, + 31, + 36 + ]); + _iterator1 = _async_iterator(modulesInsideDeletedDirectory); + _state.label = 26; + case 26: + return [ + 4, + _iterator1.next() + ]; + case 27: + if (!(_iteratorAbruptCompletion1 = !(_step1 = _state.sent()).done)) return [ + 3, + 29 + ]; + _value1 = _step1.value; + filePath1 = _value1; + removeModuleFromGraph(filePath1); + _state.label = 28; + case 28: + _iteratorAbruptCompletion1 = false; + return [ + 3, + 26 + ]; + case 29: + return [ + 3, + 36 + ]; + case 30: + err1 = _state.sent(); + _didIteratorError1 = true; + _iteratorError1 = err1; + return [ + 3, + 36 + ]; + case 31: + _state.trys.push([ + 31, + , + 34, + 35 + ]); + if (!(_iteratorAbruptCompletion1 && _iterator1.return != null)) return [ + 3, + 33 + ]; + return [ + 4, + _iterator1.return() + ]; + case 32: + _state.sent(); + _state.label = 33; + case 33: + return [ + 3, + 35 + ]; + case 34: + if (_didIteratorError1) { + throw _iteratorError1; + } + return [ + 7 + ]; + case 35: + return [ + 7 + ]; + case 36: + return [ + 3, + 37 + ]; + case 37: + return [ + 2 + ]; + } + }); + }); + return function(event, pathToModified) { + return _ref.apply(this, arguments); + }; + }() + ] + ]; + } + }); + }); + return function createDependencyGraph(directory) { + return _ref.apply(this, arguments); + }; +}(); +// src/app/lib/logger.ts +var LOG_LEVELS = { + debug: 0, + info: 1, + warn: 2, + error: 3 +}; +var Logger = /*#__PURE__*/ function() { + "use strict"; + function _Logger() { + _class_call_check(this, _Logger); + this.currentLevel = process.env.LOG_LEVEL || "info"; + } + _create_class(_Logger, [ + { + key: "setLevel", + value: function setLevel(level) { + this.currentLevel = level; + } + }, + { + key: "getLevel", + value: function getLevel() { + return this.currentLevel; + } + }, + { + key: "shouldLog", + value: function shouldLog(level) { + return LOG_LEVELS[level] >= LOG_LEVELS[this.currentLevel]; + } + }, + { + key: "debug", + value: function debug() { + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + args[_key] = arguments[_key]; + } + var _console; + if (!this.shouldLog("debug")) { + return; + } + (_console = console).debug.apply(_console, _to_consumable_array(args)); + } + }, + { + key: "info", + value: function info() { + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + args[_key] = arguments[_key]; + } + var _console; + if (!this.shouldLog("info")) { + return; + } + (_console = console).info.apply(_console, _to_consumable_array(args)); + } + }, + { + key: "warn", + value: function warn() { + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + args[_key] = arguments[_key]; + } + var _console; + if (!this.shouldLog("warn")) { + return; + } + (_console = console).warn.apply(_console, _to_consumable_array(args)); + } + }, + { + key: "error", + value: function error() { + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + args[_key] = arguments[_key]; + } + var _console; + if (!this.shouldLog("error")) { + return; + } + (_console = console).error.apply(_console, _to_consumable_array(args)); + } + } + ], [ + { + key: "getInstance", + value: function getInstance() { + if (!_Logger.instance) { + _Logger.instance = new _Logger(); + } + return _Logger.instance; + } + } + ]); + return _Logger; +}(); +var logger = Logger.getInstance(); +var logger_default = logger; +// src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts +import chalk2 from "chalk"; +var setupHotreloading = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(devServer2, documentsDirRelativePath2) { + var indexOnlyMode, clients, io, changes, reload, absolutePathToDocumentsDirectory, _ref, dependencyGraph, updateDependencyGraph, resolveDependentsOf, getFilesOutsideDocumentsDirectory, filesOutsideDocumentsDirectory, watcher, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, p, exit; + var _arguments = arguments; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + indexOnlyMode = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : false; + clients = []; + io = new SocketServer(devServer2); + io.on("connection", function(client) { + clients.push(client); + client.on("disconnect", function() { + clients = clients.filter(function(item) { + return item !== client; + }); + }); + }); + changes = []; + reload = debounce(function() { + var filteredChanges = changes.filter(function(change) { + return !path4.basename(change.filename).startsWith("."); + }).filter(function(change, index, self) { + return index === self.findIndex(function(c) { + return c.filename === change.filename && c.event === change.event; + }); + }); + if (indexOnlyMode) { + filteredChanges = filteredChanges.filter(function(change) { + return change.filename === "templates/Index.tsx" || change.filename.endsWith("Index.tsx") || path4.basename(change.filename) === "Index.tsx"; + }); + } + if (filteredChanges.length > 0) { + logger_default.info("".concat(chalk2.yellow("!"), " ").concat(chalk2.gray("Changes detected, reloading..."))); + clients.forEach(function(client) { + logger_default.debug("Emitting reload to ".concat(client.id)); + client.emit("reload", filteredChanges); + }); + } + changes = []; + }, 150); + absolutePathToDocumentsDirectory = path4.resolve(process.cwd(), documentsDirRelativePath2); + return [ + 4, + createDependencyGraph(absolutePathToDocumentsDirectory) + ]; + case 1: + _ref = _sliced_to_array.apply(void 0, [ + _state.sent(), + 2 + ]), dependencyGraph = _ref[0], updateDependencyGraph = _ref[1]; + resolveDependentsOf = function(pathToChangeTarget) { + var moduleEntry = dependencyGraph[pathToChangeTarget]; + var dependentPaths = []; + if (moduleEntry) { + var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + try { + for(var _iterator = moduleEntry.dependentPaths[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ + var dependentPath = _step.value; + var _dependentPaths; + var dependentsOfDependent = resolveDependentsOf(dependentPath); + (_dependentPaths = dependentPaths).push.apply(_dependentPaths, _to_consumable_array(dependentsOfDependent)); + dependentPaths.push(dependentPath); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally{ + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + return dependentPaths; + }; + getFilesOutsideDocumentsDirectory = function() { + return Object.keys(dependencyGraph).filter(function(p) { + return path4.relative(absolutePathToDocumentsDirectory, p).startsWith(".."); + }); + }; + filesOutsideDocumentsDirectory = getFilesOutsideDocumentsDirectory(); + watcher = watch("", { + ignoreInitial: true, + cwd: absolutePathToDocumentsDirectory, + ignored: indexOnlyMode ? [ + // 在 Index 模式下,忽略除了 Index.tsx 之外的所有文件 + function(filepath) { + var fileName = path4.basename(filepath); + var relativePath = path4.relative(absolutePathToDocumentsDirectory, filepath); + if (fileName === "Index.tsx" || relativePath === "templates/Index.tsx") { + return false; + } + return true; + }, + "**/node_modules/**", + "**/.git/**", + "**/dist/**", + "**/build/**", + "**/.next/**", + "**/coverage/**" + ] : [ + "**/node_modules/**", + "**/.git/**", + "**/dist/**", + "**/build/**", + "**/.next/**", + "**/coverage/**" + ] + }); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + try { + for(_iterator = filesOutsideDocumentsDirectory[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ + p = _step.value; + watcher.add(p); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally{ + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + } + exit = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function() { + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + return [ + 4, + watcher.close() + ]; + case 1: + _state.sent(); + return [ + 2 + ]; + } + }); + }); + return function exit() { + return _ref.apply(this, arguments); + }; + }(); + process.on("SIGINT", exit); + process.on("uncaughtException", exit); + watcher.on("all", /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(event, relativePathToChangeTarget) { + var file, pathToChangeTarget, newFilesOutsideDocumentsDirectory, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, p, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, p1, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, dependentPath; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + file = relativePathToChangeTarget.split(path4.sep); + if (file.length === 0) { + return [ + 2 + ]; + } + pathToChangeTarget = path4.resolve(absolutePathToDocumentsDirectory, relativePathToChangeTarget); + return [ + 4, + updateDependencyGraph(event, pathToChangeTarget) + ]; + case 1: + _state.sent(); + newFilesOutsideDocumentsDirectory = getFilesOutsideDocumentsDirectory(); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + try { + for(_iterator = filesOutsideDocumentsDirectory[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ + p = _step.value; + if (!newFilesOutsideDocumentsDirectory.includes(p)) { + watcher.unwatch(p); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally{ + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + } + _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined; + try { + for(_iterator1 = newFilesOutsideDocumentsDirectory[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){ + p1 = _step1.value; + if (!filesOutsideDocumentsDirectory.includes(p1)) { + watcher.add(p1); + } + } + } catch (err) { + _didIteratorError1 = true; + _iteratorError1 = err; + } finally{ + try { + if (!_iteratorNormalCompletion1 && _iterator1.return != null) { + _iterator1.return(); + } + } finally{ + if (_didIteratorError1) { + throw _iteratorError1; + } + } + } + filesOutsideDocumentsDirectory = newFilesOutsideDocumentsDirectory; + changes.push({ + event: event, + filename: relativePathToChangeTarget + }); + _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined; + try { + for(_iterator2 = resolveDependentsOf(pathToChangeTarget)[Symbol.iterator](); !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){ + dependentPath = _step2.value; + changes.push({ + event: "change", + filename: path4.relative(absolutePathToDocumentsDirectory, dependentPath) + }); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally{ + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally{ + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + reload(); + return [ + 2 + ]; + } + }); + }); + return function(event, relativePathToChangeTarget) { + return _ref.apply(this, arguments); + }; + }()); + return [ + 2, + watcher + ]; + } + }); + }); + return function setupHotreloading(devServer2, documentsDirRelativePath2) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/utils/preview/get-env-variables-for-preview-app.ts +import path5 from "path"; +var getEnvVariablesForPreviewApp = function(relativePathToDocumentsDirectory, cliPackageLocation2, cwd) { + return { + NEXT_PUBLIC_DOCUMENTS_DIR_RELATIVE_PATH: relativePathToDocumentsDirectory, + NEXT_PUBLIC_CLI_PACKAGE_LOCATION: cliPackageLocation2, + NEXT_PUBLIC_OS_PATH_SEPARATOR: path5.sep, + NEXT_PUBLIC_USER_PROJECT_LOCATION: cwd, + // new vars + DOCUMENTS_DIR_RELATIVE_PATH: relativePathToDocumentsDirectory, + DOCUMENTS_STATIC_PATH: path5.resolve(relativePathToDocumentsDirectory, "static"), + DOCUMENTS_DIR_ABSOLUTE_PATH: path5.resolve(cwd, relativePathToDocumentsDirectory), + USER_PROJECT_LOCATION: cwd + }; +}; +// src/cli/commands/dev.ts +var dev = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(param) { + var documentsDirRelativePath2, port, documentsDir, envVars, devServer2, error; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + documentsDirRelativePath2 = param.dir, port = param.port; + console.log("\u8DEF\u5F84\u5730\u5740\uFF1A", documentsDirRelativePath2); + _state.label = 1; + case 1: + _state.trys.push([ + 1, + 4, + , + 5 + ]); + if (!fs3.existsSync(documentsDirRelativePath2)) { + logger_default.error("Missing ".concat(documentsDirRelativePath2, " folder")); + throw new Error("Missing ".concat(documentsDirRelativePath2, " folder")); + } + documentsDir = path6.resolve(documentsDirRelativePath2); + envVars = getEnvVariablesForPreviewApp(path6.relative(process.cwd(), documentsDir), process.env.NEXT_PUBLIC_CLI_PACKAGE_LOCATION, process.cwd()); + Object.assign(process.env, envVars); + process.env.NEXT_PUBLIC_INDEX_ONLY_MODE = "true"; + logger_default.debug("Documents directory absolute path: ".concat(envVars.DOCUMENTS_DIR_ABSOLUTE_PATH)); + logger_default.debug("Starting dev server for ".concat(documentsDirRelativePath2, " on port ").concat(port)); + return [ + 4, + startDevServer(documentsDirRelativePath2, documentsDirRelativePath2, // defaults to ./documents/static for the static files that are served to the preview + parseInt(port)) + ]; + case 2: + devServer2 = _state.sent(); + logger_default.debug("Setting up hot reloading in Index-only mode"); + return [ + 4, + setupHotreloading(devServer2, documentsDirRelativePath2, true) + ]; + case 3: + _state.sent(); + logger_default.debug("Dev server started successfully"); + return [ + 3, + 5 + ]; + case 4: + error = _state.sent(); + logger_default.error("Error starting dev server", { + error: error + }); + process.exit(1); + return [ + 3, + 5 + ]; + case 5: + return [ + 2 + ]; + } + }); + }); + return function dev(_) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/commands/build.ts +import fs5 from "node:fs"; +import chalk3 from "chalk"; +import * as es from "esbuild"; +import path8 from "node:path"; +import postCssPlugin from "esbuild-style-plugin"; +import ora2 from "ora"; +import tailwindcss from "tailwindcss"; +import autoprefixer from "autoprefixer"; +// src/utils/htmldocs-esbuild-plugin.ts +import path7 from "node:path"; +import fs4 from "node:fs"; +import { parse as parse2 } from "react-docgen"; +import * as tsj from "ts-json-schema-generator"; +// src/utils/paths.ts +var NEXT_DIST_DIR = "dist"; +var DOCUMENT_SCHEMAS_DIR = NEXT_DIST_DIR; +// src/utils/htmldocs-esbuild-plugin.ts +var htmldocsPlugin = function(documentTemplates, isBuild) { + return { + name: "htmldocs-plugin", + setup: function(b) { + b.onLoad({ + filter: new RegExp(documentTemplates.join("|")) + }, /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(param) { + var pathToFile, contents; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + pathToFile = param.path; + return [ + 4, + fs4.promises.readFile(pathToFile, "utf8") + ]; + case 1: + contents = _state.sent(); + return [ + 4, + generateAndWriteSchema(contents, pathToFile) + ]; + case 2: + _state.sent(); + if (isBuild) { + contents = contents.replace(/\/static/g, "./static"); + } + return [ + 2, + { + contents: "".concat(contents, ";\n export { renderAsync } from 'htmldocs-module-that-will-export-render'\n "), + loader: path7.extname(pathToFile).slice(1) + } + ]; + } + }); + }); + return function(_) { + return _ref.apply(this, arguments); + }; + }()); + b.onResolve({ + filter: /^htmldocs-module-that-will-export-render$/ + }, /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(args) { + var options, result; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + options = { + kind: "import-statement", + importer: args.importer, + resolveDir: args.resolveDir, + namespace: args.namespace + }; + return [ + 4, + b.resolve("@htmldocs/render", options) + ]; + case 1: + result = _state.sent(); + if (result.errors.length === 0) { + return [ + 2, + result + ]; + } + if (result.errors.length > 0 && result.errors[0]) { + result.errors[0].text = "Failed trying to import `renderAsync` from `@htmldocs/render` to be able to render your document template.\n Maybe you don't have `@htmldocs/render` installed?"; + } + return [ + 2, + result + ]; + } + }); + }); + return function(args) { + return _ref.apply(this, arguments); + }; + }()); + } + }; +}; +function generateAndWriteSchema(contents, filePath) { + return _generateAndWriteSchema.apply(this, arguments); +} +function _generateAndWriteSchema() { + _generateAndWriteSchema = _async_to_generator(function(contents, filePath) { + var componentProps, componentInterfaceName, interfaceContent, propName, _prop_tsType, prop, required, tsType, fileContents, tempFilePath, config, schema, schemaString, baseName, schemaFilePath; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + return [ + 4, + parseFileToProps(contents, filePath) + ]; + case 1: + componentProps = _state.sent(); + componentInterfaceName = "ComponentProps"; + interfaceContent = "export interface ".concat(componentInterfaceName, " {\n"); + for(var propName in componentProps){ + ; + prop = componentProps[propName]; + if (!prop || !prop.tsType) continue; + required = prop.required ? "" : "?"; + tsType = "raw" in prop.tsType ? prop.tsType.raw : (_prop_tsType = prop.tsType) === null || _prop_tsType === void 0 ? void 0 : _prop_tsType.name; + interfaceContent += " ".concat(propName).concat(required, ": ").concat(tsType, ";\n"); + } + interfaceContent += "}\n"; + fileContents = contents + "\n" + interfaceContent; + tempFilePath = createTempFilePath(filePath); + return [ + 4, + fs4.writeFileSync(tempFilePath, fileContents) + ]; + case 2: + _state.sent(); + config = { + path: tempFilePath, + tsconfig: process.env.NEXT_PUBLIC_USER_PROJECT_LOCATION + "/tsconfig.json", + type: componentInterfaceName + }; + schema = tsj.createGenerator(config).createSchema(config.type); + fs4.unlinkSync(tempFilePath); + schemaString = JSON.stringify(schema, null, 2); + if (!fs4.existsSync(DOCUMENT_SCHEMAS_DIR)) { + fs4.mkdirSync(DOCUMENT_SCHEMAS_DIR, { + recursive: true + }); + } + baseName = path7.basename(filePath, path7.extname(filePath)); + schemaFilePath = path7.join(DOCUMENT_SCHEMAS_DIR, baseName, "".concat(baseName, ".schema.json")); + fs4.mkdirSync(path7.dirname(schemaFilePath), { + recursive: true + }); + fs4.writeFileSync(schemaFilePath, schemaString); + return [ + 2 + ]; + } + }); + }); + return _generateAndWriteSchema.apply(this, arguments); +} +function createTempFilePath(filePath) { + var baseName = path7.basename(filePath, path7.extname(filePath)); + var dirName = path7.dirname(filePath); + var extension = path7.extname(filePath).replace(".", ""); + var tempFileName = ".".concat(baseName, ".").concat(extension); + var tempFilePath = path7.join(dirName, tempFileName); + return tempFilePath; +} +var parseFileToProps = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(contents, filePath) { + var componentsInfo; + return _ts_generator(this, function(_state) { + componentsInfo = parse2(contents, { + babelOptions: { + filename: filePath, + babelrc: false + } + }); + if (componentsInfo.length > 0 && componentsInfo[0]) { + return [ + 2, + componentsInfo[0].props + ]; + } else { + return [ + 2, + void 0 + ]; + } + return [ + 2 + ]; + }); + }); + return function parseFileToProps(contents, filePath) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/commands/build.ts +import AdmZip from "adm-zip"; +var BUILD_DIR = path8.join(process.env.NEXT_PUBLIC_USER_PROJECT_LOCATION || process.cwd(), "dist"); +var cleanDistFolder = function() { + if (fs5.existsSync(BUILD_DIR)) { + fs5.rmSync(BUILD_DIR, { + recursive: true, + force: true + }); + } + fs5.mkdirSync(BUILD_DIR, { + recursive: true + }); +}; +var build2 = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(fileName) { + var write, spinner, staticPath, zip, baseName, documentBuildDir, result, error, buildFailure, error1; + var _arguments = arguments; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + write = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : true; + spinner = ora2({ + text: "Building ".concat(fileName, "...\n"), + prefixText: " " + }).start(); + closeOraOnSIGINT(spinner); + _state.label = 1; + case 1: + _state.trys.push([ + 1, + 6, + 7, + 8 + ]); + if (!fs5.existsSync(fileName)) { + spinner.fail(chalk3.red("Missing file: ".concat(fileName))); + process.exit(1); + } + spinner.text = "Cleaning dist folder..."; + cleanDistFolder(); + spinner.text = "Zipping static assets..."; + staticPath = path8.join(process.env.DOCUMENTS_DIR_ABSOLUTE_PATH, "static"); + if (fs5.existsSync(staticPath)) { + zip = new AdmZip(); + zip.addLocalFolder(staticPath, "static"); + zip.writeZip(path8.join(BUILD_DIR, "static.zip")); + spinner.succeed("Static assets zipped"); + } + spinner.text = "Building ".concat(fileName, "...\n"); + baseName = path8.basename(fileName, path8.extname(fileName)); + documentBuildDir = path8.join(BUILD_DIR, baseName); + _state.label = 2; + case 2: + _state.trys.push([ + 2, + 4, + , + 5 + ]); + return [ + 4, + es.build({ + entryPoints: [ + fileName + ], + bundle: true, + minify: true, + write: write, + format: "cjs", + jsx: "automatic", + platform: "node", + define: { + "process.env.NODE_ENV": '"development"' + }, + loader: { + ".ts": "ts", + ".tsx": "tsx", + ".css": "css" + }, + plugins: [ + htmldocsPlugin([ + fileName + ], true), + postCssPlugin({ + postcss: { + plugins: [ + tailwindcss, + autoprefixer + ] + } + }) + ], + outdir: documentBuildDir, + sourcemap: "external" + }) + ]; + case 3: + result = _state.sent(); + spinner.succeed("Build completed"); + return [ + 2, + result + ]; + case 4: + error = _state.sent(); + spinner.fail("Build failed"); + buildFailure = error; + console.error({ + error: { + message: buildFailure.message, + stack: buildFailure.stack, + name: buildFailure.name, + cause: buildFailure.cause + } + }); + process.exit(1); + return [ + 3, + 5 + ]; + case 5: + return [ + 3, + 8 + ]; + case 6: + error1 = _state.sent(); + spinner.fail("Build failed"); + console.error(error1); + process.exit(1); + return [ + 3, + 8 + ]; + case 7: + spinner.stop(); + return [ + 7 + ]; + case 8: + return [ + 2 + ]; + } + }); + }); + return function build2(fileName) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/commands/publish.ts +import chalk4 from "chalk"; +import { tmpdir } from "os"; +import { promises as fs7, createReadStream } from "fs"; +import path10 from "path"; +import AdmZip2 from "adm-zip"; +import FormData from "form-data"; +import fetch2 from "node-fetch"; +// src/cli/utils/token.ts +import fs6 from "node:fs"; +import os from "node:os"; +import path9 from "node:path"; +import { z } from "zod"; +var TokenConfigSchema = z.object({ + team_id: z.string(), + api_key: z.string() +}); +var configPath = path9.join(os.homedir(), ".htmldocs.json"); +function storeToken(teamId, apiKey) { + return _storeToken.apply(this, arguments); +} +function _storeToken() { + _storeToken = _async_to_generator(function(teamId, apiKey) { + var configData; + return _ts_generator(this, function(_state) { + configData = { + team_id: teamId, + api_key: apiKey + }; + fs6.writeFileSync(configPath, JSON.stringify(configData, null, 2)); + return [ + 2 + ]; + }); + }); + return _storeToken.apply(this, arguments); +} +function getToken() { + return _getToken.apply(this, arguments); +} +function _getToken() { + _getToken = _async_to_generator(function() { + var configData, parsedData; + return _ts_generator(this, function(_state) { + try { + configData = fs6.readFileSync(configPath, "utf8"); + parsedData = TokenConfigSchema.safeParse(JSON.parse(configData)); + if (!parsedData.success) { + console.error("Invalid token configuration:", parsedData.error); + throw new Error("Invalid token configuration"); + } + return [ + 2, + parsedData.data + ]; + } catch (error) { + console.error("Error reading or parsing token config:", error); + throw new Error("Invalid token configuration"); + } + return [ + 2 + ]; + }); + }); + return _getToken.apply(this, arguments); +} +// src/cli/commands/publish.ts +import { configureSourceMap, createFakeContext, executeBuiltCode, extractOutputFiles } from "@htmldocs/render"; +import ora3 from "ora"; +var publish = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(documentPath) { + var result, outputFiles, baseName, documentBuildDir, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, outputFile, filePath, err, _ref, documentId, defaultProps, zipPath, _ref1, team_id, api_key, formData, spinner, response, error; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + logger_default.debug("Starting publish process for document: ".concat(documentPath)); + return [ + 4, + build2(documentPath, false) + ]; + case 1: + result = _state.sent(); + outputFiles = result.outputFiles; + if (!outputFiles) { + logger_default.error("No output files found"); + return [ + 2 + ]; + } + baseName = path10.basename(documentPath, path10.extname(documentPath)); + documentBuildDir = path10.join(BUILD_DIR, baseName); + logger_default.debug("Found ".concat(outputFiles.length, " output files")); + logger_default.debug("Writing output files..."); + return [ + 4, + fs7.mkdir(documentBuildDir, { + recursive: true + }) + ]; + case 2: + _state.sent(); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + _state.label = 3; + case 3: + _state.trys.push([ + 3, + 8, + 9, + 10 + ]); + _iterator = outputFiles[Symbol.iterator](); + _state.label = 4; + case 4: + if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [ + 3, + 7 + ]; + outputFile = _step.value; + filePath = path10.join(documentBuildDir, path10.basename(outputFile.path)); + return [ + 4, + fs7.writeFile(filePath, outputFile.contents) + ]; + case 5: + _state.sent(); + logger_default.debug("Wrote file: ".concat(filePath)); + _state.label = 6; + case 6: + _iteratorNormalCompletion = true; + return [ + 3, + 4 + ]; + case 7: + return [ + 3, + 10 + ]; + case 8: + err = _state.sent(); + _didIteratorError = true; + _iteratorError = err; + return [ + 3, + 10 + ]; + case 9: + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + return [ + 7 + ]; + case 10: + logger_default.debug("Finished writing output files"); + return [ + 4, + getDocumentIdAndDefaultProps(documentPath, outputFiles) + ]; + case 11: + _ref = _state.sent(), documentId = _ref.documentId, defaultProps = _ref.defaultProps; + logger_default.debug("Document ID: ".concat(documentId)); + return [ + 4, + zipDocumentFiles(documentBuildDir) + ]; + case 12: + zipPath = _state.sent(); + logger_default.debug("Zipped document files to: ".concat(zipPath)); + return [ + 4, + getToken() + ]; + case 13: + _ref1 = _state.sent(), team_id = _ref1.team_id, api_key = _ref1.api_key; + logger_default.debug("Retrieved token for team: ".concat(team_id)); + formData = new FormData(); + formData.append("file", createReadStream(path10.join(zipPath, "output.zip"))); + formData.append("teamId", team_id); + formData.append("documentName", documentId); + formData.append("defaultProps", JSON.stringify(defaultProps)); + logger_default.debug("Form data prepared for upload"); + spinner = ora3({ + text: 'Uploading document "'.concat(documentId, '"...'), + prefixText: " " + }).start(); + closeOraOnSIGINT(spinner); + _state.label = 14; + case 14: + _state.trys.push([ + 14, + 16, + , + 17 + ]); + logger_default.debug("Sending upload request to server"); + return [ + 4, + fetch2("https://htmldocs.com/api/documents/upload", { + method: "POST", + headers: { + "Authorization": "Bearer ".concat(api_key) + }, + body: formData + }) + ]; + case 15: + response = _state.sent(); + if (!response.ok) { + logger_default.error("Upload failed with status: ".concat(response.status)); + spinner.fail(chalk4.red("Failed to upload document: ".concat(response.statusText))); + return [ + 2 + ]; + } + logger_default.debug("Upload successful"); + spinner.succeed(chalk4.green('Document "'.concat(documentId, '" published'))); + return [ + 3, + 17 + ]; + case 16: + error = _state.sent(); + logger_default.error("Error during upload:", error); + spinner.fail(chalk4.red("Could not connect to the server. Please check your internet connection and try again.")); + return [ + 2 + ]; + case 17: + return [ + 2 + ]; + } + }); + }); + return function publish(documentPath) { + return _ref.apply(this, arguments); + }; +}(); +var getDocumentIdAndDefaultProps = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(documentPath, outputFiles) { + var _extractOutputFiles, sourceMapFile, bundledDocumentFile, builtDocumentCode, fakeContext, sourceMapToDocument, executionResult, documentId, defaultProps; + return _ts_generator(this, function(_state) { + logger_default.debug("Extracting document ID"); + _extractOutputFiles = extractOutputFiles(outputFiles), sourceMapFile = _extractOutputFiles.sourceMapFile, bundledDocumentFile = _extractOutputFiles.bundledDocumentFile; + builtDocumentCode = bundledDocumentFile.text; + fakeContext = createFakeContext(documentPath); + sourceMapToDocument = configureSourceMap(sourceMapFile); + logger_default.debug("Executing built code to extract document ID"); + executionResult = executeBuiltCode(builtDocumentCode, fakeContext, documentPath, sourceMapToDocument); + if ("error" in executionResult) { + logger_default.error("Error building document"); + logger_default.error(executionResult.error); + return [ + 2, + { + documentId: null, + defaultProps: {} + } + ]; + } + documentId = executionResult.DocumentComponent.documentId; + if (!documentId) { + logger_default.error("No document ID found. Please ensure documentId is set as a property on the default export."); + return [ + 2, + { + documentId: null, + defaultProps: {} + } + ]; + } + defaultProps = executionResult.DocumentComponent.PreviewProps || {}; + logger_default.debug("Extracted document ID: ".concat(documentId)); + logger_default.debug("Extracted default props: ".concat(JSON.stringify(defaultProps, null, 2))); + return [ + 2, + { + documentId: documentId, + defaultProps: defaultProps + } + ]; + }); + }); + return function getDocumentIdAndDefaultProps(documentPath, outputFiles) { + return _ref.apply(this, arguments); + }; +}(); +var zipDocumentFiles = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(documentBuildDir) { + var zip, files, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, filePath, staticZipPath, tempDir, zipFilePath; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + logger_default.debug("Starting to zip document files"); + zip = new AdmZip2(); + return [ + 4, + fs7.readdir(documentBuildDir) + ]; + case 1: + files = _state.sent(); + _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; + try { + for(_iterator = files[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ + file = _step.value; + filePath = path10.join(documentBuildDir, file); + logger_default.debug("Adding file to zip: ".concat(filePath)); + zip.addLocalFile(filePath); + logger_default.debug("File added to zip: ".concat(filePath)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally{ + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally{ + if (_didIteratorError) { + throw _iteratorError; + } + } + } + staticZipPath = path10.join(BUILD_DIR, "static.zip"); + return [ + 4, + fs7.access(staticZipPath).then(function() { + return true; + }).catch(function() { + return false; + }) + ]; + case 2: + if (_state.sent()) { + logger_default.debug("Adding static.zip to bundle"); + zip.addLocalFile(staticZipPath); + } + tempDir = path10.join(tmpdir(), "htmldocs-".concat(Date.now())); + logger_default.debug("Creating temporary directory: ".concat(tempDir)); + return [ + 4, + fs7.mkdir(tempDir, { + recursive: true + }) + ]; + case 3: + _state.sent(); + zipFilePath = path10.join(tempDir, "output.zip"); + logger_default.debug("Writing zip file to: ".concat(zipFilePath)); + zip.writeZip(zipFilePath); + logger_default.debug("Zip process completed"); + return [ + 2, + tempDir + ]; + } + }); + }); + return function zipDocumentFiles(documentBuildDir) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/commands/login.ts +import chalk5 from "chalk"; +import open from "open"; +import os2 from "os"; +import { URL } from "url"; +import crypto from "crypto"; +var apiUrl = "https://htmldocs.com"; +var TIMEOUT_MS = 5 * 60 * 1e3; +var POLLING_INTERVAL_MS = 1e3; +var login = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function() { + var options, sessionId, fullHostname, cleanHostname, sessionResponse, _$error, callbackData, encodedData, url2, startTime, response, data, error, error1; + var _arguments = arguments; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}; + sessionId = crypto.randomBytes(16).toString("hex"); + fullHostname = os2.hostname(); + cleanHostname = fullHostname.split(".")[0]; + _state.label = 1; + case 1: + _state.trys.push([ + 1, + 19, + , + 20 + ]); + return [ + 4, + fetch("".concat(apiUrl, "/api/auth/create-session"), { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + session_id: sessionId, + hostname: cleanHostname + }) + }) + ]; + case 2: + sessionResponse = _state.sent(); + if (!!sessionResponse.ok) return [ + 3, + 4 + ]; + return [ + 4, + sessionResponse.json() + ]; + case 3: + _$error = _state.sent(); + console.log(chalk5.red("Failed to initialize authentication:", _$error.message)); + process.exit(1); + _state.label = 4; + case 4: + callbackData = { + session_id: sessionId, + hostname: cleanHostname + }; + encodedData = Buffer.from(JSON.stringify(callbackData)).toString("base64"); + url2 = new URL("".concat(apiUrl, "/authorize")); + url2.searchParams.set("callback", encodedData); + if (!options.headless) return [ + 3, + 5 + ]; + console.log(url2.toString()); + return [ + 2 + ]; + case 5: + return [ + 4, + open(url2.toString()) + ]; + case 6: + _state.sent(); + console.log(chalk5.blue("Please select a team and complete the authentication in your browser.")); + _state.label = 7; + case 7: + logger_default.debug("Starting CLI auth request with session ID:", sessionId); + startTime = Date.now(); + _state.label = 8; + case 8: + if (!true) return [ + 3, + 18 + ]; + if (Date.now() - startTime > TIMEOUT_MS) { + console.log(chalk5.red("Authentication timed out. Please try again.")); + process.exit(1); + } + _state.label = 9; + case 9: + _state.trys.push([ + 9, + 16, + , + 17 + ]); + return [ + 4, + fetch("".concat(apiUrl, "/api/auth/check-status?session_id=").concat(sessionId)) + ]; + case 10: + response = _state.sent(); + return [ + 4, + response.json() + ]; + case 11: + data = _state.sent(); + if (!(data.status === "completed" && data.team_id && data.api_key)) return [ + 3, + 13 + ]; + return [ + 4, + storeToken(data.team_id, data.api_key) + ]; + case 12: + _state.sent(); + console.log(chalk5.green("Login successful and API key stored.")); + process.exit(0); + return [ + 3, + 14 + ]; + case 13: + if (data.status === "error") { + console.log(chalk5.red("Authentication failed:", data.message)); + process.exit(1); + } + _state.label = 14; + case 14: + return [ + 4, + new Promise(function(resolve) { + return setTimeout(resolve, POLLING_INTERVAL_MS); + }) + ]; + case 15: + _state.sent(); + return [ + 3, + 17 + ]; + case 16: + error = _state.sent(); + console.log(chalk5.red("Error checking authentication status. Please try again.")); + process.exit(1); + return [ + 3, + 17 + ]; + case 17: + return [ + 3, + 8 + ]; + case 18: + return [ + 3, + 20 + ]; + case 19: + error1 = _state.sent(); + console.log(chalk5.red("Failed to start authentication process:", error1)); + process.exit(1); + return [ + 3, + 20 + ]; + case 20: + return [ + 2 + ]; + } + }); + }); + return function login() { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/commands/init.ts +import path11 from "node:path"; +import fse from "fs-extra"; +import logSymbols2 from "log-symbols"; +import ora4 from "ora"; +import { exec } from "child_process"; +import chalk6 from "chalk"; +var init = /*#__PURE__*/ function() { + var _ref = _async_to_generator(function(projectName) { + var spinner, projectPath, templatePath, resolvedProjectPath, templatePackageJsonPath, templatePackageJson, key, error; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + logger_default.debug("CLI package location", process.env.NEXT_PUBLIC_CLI_PACKAGE_LOCATION); + if (!process.env.NEXT_PUBLIC_CLI_PACKAGE_LOCATION) { + logger_default.error("NEXT_PUBLIC_CLI_PACKAGE_LOCATION is not set"); + process.exit(1); + } + spinner = ora4("Preparing files...\n").start(); + projectPath = projectName; + if (!projectPath) { + projectPath = path11.join(process.cwd(), "htmldocs-starter"); + } + if (typeof projectPath === "string") { + projectPath = projectPath.trim(); + } + templatePath = path11.resolve(cliPackageLocation, "cli/template"); + resolvedProjectPath = path11.resolve(projectPath); + fse.copySync(templatePath, resolvedProjectPath, { + recursive: true + }); + templatePackageJsonPath = path11.resolve(resolvedProjectPath, "./package.json"); + templatePackageJson = JSON.parse(fse.readFileSync(templatePackageJsonPath, "utf8")); + for(var key in templatePackageJson.dependencies){ + templatePackageJson.dependencies[key] = templatePackageJson.dependencies[key].replace("workspace:", ""); + } + fse.writeFileSync(templatePackageJsonPath, JSON.stringify(templatePackageJson, null, 2), "utf8"); + spinner.text = "Installing dependencies..."; + _state.label = 1; + case 1: + _state.trys.push([ + 1, + 4, + , + 5 + ]); + return [ + 4, + new Promise(function(resolve, reject) { + spinner.text = "Installing dependencies..."; + exec("npm install", { + cwd: resolvedProjectPath + }, function(error, stdout, stderr) { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }) + ]; + case 2: + _state.sent(); + spinner.text = "Installing Playwright..."; + return [ + 4, + new Promise(function(resolve, reject) { + exec("npx playwright install", { + cwd: resolvedProjectPath + }, function(error, stdout, stderr) { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }) + ]; + case 3: + _state.sent(); + spinner.succeed(chalk6.green('Created project "'.concat(projectName, '" and installed dependencies'))); + console.log("\n" + chalk6.blue(logSymbols2.info) + chalk6.bold(" To start your project:")); + console.log(chalk6.cyan(" cd ".concat(projectName))); + console.log(chalk6.cyan(" npm run dev")); + return [ + 3, + 5 + ]; + case 4: + error = _state.sent(); + spinner.fail(chalk6.red("Failed to install dependencies")); + logger_default.error("Error installing dependencies:", error); + process.exit(1); + return [ + 3, + 5 + ]; + case 5: + return [ + 2 + ]; + } + }); + }); + return function init(projectName) { + return _ref.apply(this, arguments); + }; +}(); +// src/cli/index.ts +import inquirer from "inquirer"; +import path12 from "path"; +var _process_env_NEXT_PUBLIC_DOCUMENTS_DIR_RELATIVE_PATH; +// src/utils/documents-directory-absolute-path.tsx +var documentsDirRelativePath = (_process_env_NEXT_PUBLIC_DOCUMENTS_DIR_RELATIVE_PATH = process.env.NEXT_PUBLIC_DOCUMENTS_DIR_RELATIVE_PATH) !== null && _process_env_NEXT_PUBLIC_DOCUMENTS_DIR_RELATIVE_PATH !== void 0 ? _process_env_NEXT_PUBLIC_DOCUMENTS_DIR_RELATIVE_PATH : "documents"; +var userProjectLocation = process.env.NEXT_PUBLIC_USER_PROJECT_LOCATION; +var pathSeparator = process.env.NEXT_PUBLIC_OS_PATH_SEPARATOR; +var documentsDirectoryAbsolutePath = process.env.DOCUMENTS_DIR_ABSOLUTE_PATH; +// src/cli/index.ts +var PACKAGE_NAME = "htmldocs"; +var noop = function() {}; +process.removeAllListeners("warning"); +var originalError = logger_default.error; +logger_default.error = function() { + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + args[_key] = arguments[_key]; + } + originalError.apply(logger_default, args); + process.exit(1); +}; +process.env = _object_spread({}, process.env, getEnvVariablesForPreviewApp(// If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens. +path12.normalize(documentsDirRelativePath), cliPackageLocation, process.cwd())); +program.name(PACKAGE_NAME).description("A live preview of your documents right in your browser").version(package_default.version).option("-v, --verbose", "Enable verbose logging").hook("preAction", function(thisCommand) { + if (thisCommand.opts().verbose) { + logger_default.setLevel("debug"); + } +}); +program.command("dev").description("Starts the preview server").option("-d, --dir ", "Directory with your document templates", "./documents").option("-p --port ", "Port to run dev server on", "3000").action(dev); +program.command("build ", { + hidden: true +}).description("Builds the document component").action(function(file) { + return build2(file).then(noop); +}); +program.command("publish ").description("Publishes the document to the cloud for API use").action(function(file) { + return publish(file); +}); +program.command("login").description("Authenticates the CLI with the cloud").option("--headless", "Print the authorization URL instead of opening it").action(login); +program.command("init [name]").description("Initialize a new HTMLDocs project").action(/*#__PURE__*/ function() { + var _ref = _async_to_generator(function(name) { + var answer; + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + if (!!name) return [ + 3, + 2 + ]; + return [ + 4, + inquirer.prompt([ + { + type: "input", + name: "projectName", + message: "What is the name of your project?", + default: "htmldocs" + } + ]) + ]; + case 1: + answer = _state.sent(); + name = answer.projectName; + _state.label = 2; + case 2: + return [ + 4, + init(name) + ]; + case 3: + _state.sent(); + return [ + 2 + ]; + } + }); + }); + return function(name) { + return _ref.apply(this, arguments); + }; +}()); +program.parse(); diff --git a/packages/htmldocs/dist/cli/template/CHANGELOG.md b/packages/htmldocs/dist/cli/template/CHANGELOG.md new file mode 100644 index 0000000..26f5f2e --- /dev/null +++ b/packages/htmldocs/dist/cli/template/CHANGELOG.md @@ -0,0 +1,169 @@ +# htmldocs-starter + +## 0.2.30 + +### Patch Changes + +- Updated dependencies [c6753c4] + - htmldocs@0.2.30 + - @htmldocs/react@0.2.30 + - @htmldocs/render@0.2.30 + +## 0.2.29 + +### Patch Changes + +- Updated dependencies [ddd6fbc] + - htmldocs@0.2.29 + - @htmldocs/react@0.2.29 + - @htmldocs/render@0.2.29 + +## 0.2.28 + +### Patch Changes + +- Updated dependencies [abdcd3a] + - htmldocs@0.2.28 + - @htmldocs/react@0.2.28 + - @htmldocs/render@0.2.28 + +## 0.2.27 + +### Patch Changes + +- Updated dependencies [d232426] + - htmldocs@0.2.27 + - @htmldocs/react@0.2.27 + - @htmldocs/render@0.2.27 + +## 0.2.26 + +### Patch Changes + +- 2fc14f7: fix build +- Updated dependencies [2fc14f7] + - htmldocs@0.2.26 + - @htmldocs/react@0.2.26 + - @htmldocs/render@0.2.26 + +## 0.2.25 + +### Patch Changes + +- c737b5f: add new version popup + - @htmldocs/react@0.2.25 + - @htmldocs/render@0.2.25 + +## 0.2.24 + +### Patch Changes + +- Updated dependencies [9e2b062] + - htmldocs@0.2.24 + - @htmldocs/react@0.2.24 + - @htmldocs/render@0.2.24 + +## 0.2.23 + +### Patch Changes + +- Updated dependencies [7043ac8] + - htmldocs@0.2.23 + - @htmldocs/render@0.2.23 + - @htmldocs/react@0.2.23 + +## 0.2.22 + +### Patch Changes + +- Updated dependencies [7a5492d] + - htmldocs@0.2.22 + - @htmldocs/react@0.2.22 + - @htmldocs/render@0.2.22 + +## 0.2.21 + +### Patch Changes + +- b0c33de: expand hot refresh to cwd +- Updated dependencies [b0c33de] + - htmldocs@0.2.21 + - @htmldocs/react@0.2.21 + - @htmldocs/render@0.2.21 + +## 0.2.20 + +### Patch Changes + +- Updated dependencies [91e3544] +- Updated dependencies [d5f8135] + - @htmldocs/render@0.2.20 + - htmldocs@0.2.20 + - @htmldocs/react@0.2.20 + +## 0.2.19 + +### Patch Changes + +- Updated dependencies [fa33e6f] + - htmldocs@0.2.19 + - @htmldocs/react@0.2.19 + - @htmldocs/render@0.2.19 + +## 0.2.18 + +### Patch Changes + +- 60f8e6b: improve logging, dev experience +- Updated dependencies [60f8e6b] + - htmldocs@0.2.18 + - @htmldocs/render@0.2.18 + - @htmldocs/react@0.2.18 + +## 0.2.17 + +### Patch Changes + +- 191eb52: restore packages +- Updated dependencies [191eb52] + - htmldocs@0.2.17 + - @htmldocs/render@0.2.17 + - @htmldocs/react@0.2.17 + +## 0.2.16 + +### Patch Changes + +- 8787d4b: add .npmignore +- Updated dependencies [8787d4b] + - htmldocs@0.2.16 + - @htmldocs/render@0.2.16 + - @htmldocs/react@0.2.16 + +## 0.2.15 + +### Patch Changes + +- 23ac0f9: reduce bundle size +- Updated dependencies [23ac0f9] + - htmldocs@0.2.15 + - @htmldocs/react@0.2.15 + - @htmldocs/render@0.2.15 + +## 0.2.14 + +### Patch Changes + +- Updated dependencies [a6c234f] + - htmldocs@0.2.14 + - @htmldocs/react@0.2.14 + - @htmldocs/render@0.2.14 + +## 0.2.13 + +### Patch Changes + +- Updated dependencies [accc5e7] + - htmldocs@0.2.13 + - @htmldocs/react@0.2.13 + - @htmldocs/render@0.2.13 diff --git a/packages/htmldocs/dist/cli/template/documents/static/axis.svg b/packages/htmldocs/dist/cli/template/documents/static/axis.svg new file mode 100644 index 0000000..bc03a41 --- /dev/null +++ b/packages/htmldocs/dist/cli/template/documents/static/axis.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/htmldocs/dist/cli/template/documents/static/content.md b/packages/htmldocs/dist/cli/template/documents/static/content.md new file mode 100644 index 0000000..57d2343 --- /dev/null +++ b/packages/htmldocs/dist/cli/template/documents/static/content.md @@ -0,0 +1,186 @@ +### Chapter 1. +Loomings. +========= + +Call me Ishmael. Some years ago — never mind how long precisely — having little +or no money in my purse, and nothing particular to interest me on shore, I +thought I would sail about a little and see the watery part of the world. It is +a way I have of driving off the spleen and regulating the circulation. Whenever +I find myself growing grim about the mouth; whenever it is a damp, drizzly +November in my soul; whenever I find myself involuntarily pausing before coffin +warehouses, and bringing up the rear of every funeral I meet; and especially +whenever my hypos get such an upper hand of me, that it requires a strong moral +principle to prevent me from deliberately stepping into the street, and +methodically knocking people’s hats off — then, I account it high time to get to +sea as soon as I can. This is my substitute for pistol and ball. With a +philosophical flourish Cato throws himself upon his sword; I quietly take to the +ship. There is nothing surprising in this. If they but knew it, almost all men +in their degree, some time or other, cherish very nearly the same feelings +towards the ocean with me. + +There now is your insular city of the Manhattoes, belted round by wharves as +Indian isles by coral reefs — commerce surrounds it with her surf. Right and +left, the streets take you waterward. Its extreme downtown is the battery, where +that noble mole is washed by waves, and cooled by breezes, which a few hours +previous were out of sight of land. Look at the crowds of water-gazers there. + +Circumambulate the city of a dreamy Sabbath afternoon. Go from Corlears Hook to +Coenties Slip, and from thence, by Whitehall, northward. What do you see? — +Posted like silent sentinels all around the town, stand thousands upon thousands +of mortal men fixed in ocean reveries. Some leaning against the spiles; some +seated upon the pier-heads; some looking over the bulwarks of ships from China; +some high aloft in the rigging, as if striving to get a still better seaward +peep. But these are all landsmen; of week days pent up in lath and plaster — +tied to counters, nailed to benches, clinched to desks. How then is this? Are +the green fields gone? What do they here? + +But look! here come more crowds, pacing straight for the water, and seemingly +bound for a dive. Strange! Nothing will content them but the extremest limit of +the land; loitering under the shady lee of yonder warehouses will not suffice. +No. They must get just as nigh the water as they possibly can without falling +in. And there they stand — miles of them — leagues. Inlanders all, they come +from lanes and alleys, streets and avenues — north, east, south, and west. Yet +here they all unite. Tell me, does the magnetic virtue of the needles of the +compasses of all those ships attract them thither? + +Once more. Say you are in the country; in some high land of lakes. Take almost +any path you please, and ten to one it carries you down in a dale, and leaves +you there by a pool in the stream. There is magic in it. Let the most +absent-minded of men be plunged in his deepest reveries — stand that man on his +legs, set his feet a-going, and he will infallibly lead you to water, if water +there be in all that region. Should you ever be athirst in the great American +desert, try this experiment, if your caravan happen to be supplied with a +metaphysical professor. Yes, as every one knows, meditation and water are wedded +for ever. + +But here is an artist. He desires to paint you the dreamiest, shadiest, +quietest, most enchanting bit of romantic landscape in all the valley of the +Saco. What is the chief element he employs? There stand his trees, each with a +hollow trunk, as if a hermit and a crucifix were within; and here sleeps his +meadow, and there sleep his cattle; and up from yonder cottage goes a sleepy +smoke. Deep into distant woodlands winds a mazy way, reaching to overlapping +spurs of mountains bathed in their hill-side blue. But though the picture lies +thus tranced, and though this pine-tree shakes down its sighs like leaves upon +this shepherd’s head, yet all were vain, unless the shepherd’s eye were fixed +upon the magic stream before him. Go visit the Prairies in June, when for scores +on scores of miles you wade knee-deep among Tiger-lilies — what is the one charm +wanting? — Water — there is not a drop of water there! Were Niagara but a +cataract of sand, would you travel your thousand miles to see it? Why did the +poor poet of Tennessee, upon suddenly receiving two handfuls of silver, +deliberate whether to buy him a coat, which he sadly needed, or invest his money +in a pedestrian trip to Rockaway Beach? Why is almost every robust healthy boy +with a robust healthy soul in him, at some time or other crazy to go to sea? Why +upon your first voyage as a passenger, did you yourself feel such a mystical +vibration, when first told that you and your ship were now out of sight of land? +Why did the old Persians hold the sea holy? Why did the Greeks give it a +separate deity, and own brother of Jove? Surely all this is not without meaning. +And still deeper the meaning of that story of Narcissus, who because he could +not grasp the tormenting, mild image he saw in the fountain, plunged into it and +was drowned. But that same image, we ourselves see in all rivers and oceans. It +is the image of the ungraspable phantom of life; and this is the key to it all. + +Now, when I say that I am in the habit of going to sea whenever I begin to grow +hazy about the eyes, and begin to be over conscious of my lungs, I do not mean +to have it inferred that I ever go to sea as a passenger. For to go as a +passenger you must needs have a purse, and a purse is but a rag unless you have +something in it. Besides, passengers get sea-sick — grow quarrelsome — don’t +sleep of nights — do not enjoy themselves much, as a general thing; — no, I +never go as a passenger; nor, though I am something of a salt, do I ever go to +sea as a Commodore, or a Captain, or a Cook. I abandon the glory and distinction +of such offices to those who like them. For my part, I abominate all honourable +respectable toils, trials, and tribulations of every kind whatsoever. It is +quite as much as I can do to take care of myself, without taking care of ships, +barques, brigs, schooners, and what not. And as for going as cook, — though I +confess there is considerable glory in that, a cook being a sort of officer on +ship-board — yet, somehow, I never fancied broiling fowls; — though once +broiled, judiciously buttered, and judgmatically salted and peppered, there is +no one who will speak more respectfully, not to say reverentially, of a broiled +fowl than I will. It is out of the idolatrous dotings of the old Egyptians upon +broiled ibis and roasted river horse, that you see the mummies of those +creatures in their huge bake-houses the pyramids. + +No, when I go to sea, I go as a simple sailor, right before the mast, plumb down +into the forecastle, aloft there to the royal mast-head. True, they rather +order me about some, and make me jump from spar to spar, like a grasshopper in a +May meadow. And at first, this sort of thing is unpleasant enough. It touches +one’s sense of honour, particularly if you come of an old established family in +the land, the Van Rensselaers, or Randolphs, or Hardicanutes. And more than all, +if just previous to putting your hand into the tar-pot, you have been lording it +as a country schoolmaster, making the tallest boys stand in awe of you. The +transition is a keen one, I assure you, from a schoolmaster to a sailor, and +requires a strong decoction of Seneca and the Stoics to enable you to grin and +bear it. But even this wears off in time. + +What of it, if some old hunks of a sea-captain orders me to get a broom and +sweep down the decks? What does that indignity amount to, weighed, I mean, in +the scales of the New Testament? Do you think the archangel Gabriel thinks +anything the less of me, because I promptly and respectfully obey that old hunks +in that particular instance? Who ain’t a slave? Tell me that. Well, then, +however the old sea-captains may order me about — however they may thump and +punch me about, I have the satisfaction of knowing that it is all right; that +everybody else is one way or other served in much the same way — either in a +physical or metaphysical point of view, that is; and so the universal thump is +passed round, and all hands should rub each other’s shoulder-blades, and be +content. + +Again, I always go to sea as a sailor, because they make a point of paying me +for my trouble, whereas they never pay passengers a single penny that I ever +heard of. On the contrary, passengers themselves must pay. And there is all the +difference in the world between paying and being paid. The act of paying is +perhaps the most uncomfortable infliction that the two orchard thieves entailed +upon us. But *being paid,* — what will compare with it? The urbane activity with +which a man receives money is really marvellous, considering that we so +earnestly believe money to be the root of all earthly ills, and that on no +account can a monied man enter heaven. Ah! how cheerfully we consign ourselves +to perdition! + +Finally, I always go to sea as a sailor, because of the wholesome exercise and +pure air of the fore-castle deck. For as in this world, head winds are far more +prevalent than winds from astern (that is, if you never violate the Pythagorean +maxim), so for the most part the Commodore on the quarter-deck gets his +atmosphere at second hand from the sailors on the forecastle. He thinks he +breathes it first; but not so. In much the same way do the commonalty lead their +leaders in many other things, at the same time that the leaders little suspect +it. But wherefore it was that after having repeatedly smelt the sea as a +merchant sailor, I should now take it into my head to go on a whaling voyage; +this the invisible police officer of the Fates, who has the constant +surveillance of me, and secretly dogs me, and influences me in some +unaccountable way — he can better answer than any one else. And, doubtless, my +going on this whaling voyage, formed part of the grand programme of Providence +that was drawn up a long time ago. It came in as a sort of brief interlude and +solo between more extensive performances. I take it that this part of the bill +must have run something like this: + +__“Grand Contested Election for the Presidency of the United States.”__ + +__“Whaling Voyage by One Ishmael.”__ + +__“Bloody Battle in Affghanistan.”__ + +Though I cannot tell why it was exactly that those stage managers, the Fates, +put me down for this shabby part of a whaling voyage, when others were set down +for magnificent parts in high tragedies, and short and easy parts in genteel +comedies, and jolly parts in farces — though I cannot tell why this was exactly; +yet, now that I recall all the circumstances, I think I can see a little into +the springs and motives which being cunningly presented to me under various +disguises, induced me to set about performing the part I did, besides cajoling +me into the delusion that it was a choice resulting from my own unbiased +freewill and discriminating judgment. + +Chief among these motives was the overwhelming idea of the great whale himself. +Such a portentous and mysterious monster roused all my curiosity. Then the wild +and distant seas where he rolled his island bulk; the undeliverable, nameless +perils of the whale; these, with all the attending marvels of a thousand +Patagonian sights and sounds, helped to sway me to my wish. With other men, +perhaps, such things would not have been inducements; but as for me, I am +tormented with an everlasting itch for things remote. I love to sail forbidden +seas, and land on barbarous coasts. Not ignoring what is good, I am quick to +perceive a horror, and could still be social with it — would they let me — since +it is but well to be on friendly terms with all the inmates of the place one +lodges in. + +By reason of these things, then, the whaling voyage was welcome; the great +flood-gates of the wonder-world swung open, and in the wild conceits that swayed +me to my purpose, two and two there floated into my inmost soul, endless +processions of the whale, and, mid most of them all, one grand hooded phantom, +like a snow hill in the air. \ No newline at end of file diff --git a/packages/htmldocs/dist/cli/template/documents/static/fonts/PPEiko-Medium.otf b/packages/htmldocs/dist/cli/template/documents/static/fonts/PPEiko-Medium.otf new file mode 100644 index 0000000..f1fff57 Binary files /dev/null and b/packages/htmldocs/dist/cli/template/documents/static/fonts/PPEiko-Medium.otf differ diff --git a/packages/htmldocs/dist/cli/template/documents/static/logo.svg b/packages/htmldocs/dist/cli/template/documents/static/logo.svg new file mode 100644 index 0000000..d321785 --- /dev/null +++ b/packages/htmldocs/dist/cli/template/documents/static/logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/htmldocs/dist/cli/template/documents/static/placeholder.svg b/packages/htmldocs/dist/cli/template/documents/static/placeholder.svg new file mode 100644 index 0000000..e763910 --- /dev/null +++ b/packages/htmldocs/dist/cli/template/documents/static/placeholder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/htmldocs/dist/cli/template/documents/static/techflow.svg b/packages/htmldocs/dist/cli/template/documents/static/techflow.svg new file mode 100644 index 0000000..a991ca0 --- /dev/null +++ b/packages/htmldocs/dist/cli/template/documents/static/techflow.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/htmldocs/dist/cli/template/documents/templates/Book.tsx b/packages/htmldocs/dist/cli/template/documents/templates/Book.tsx new file mode 100644 index 0000000..0a3b404 --- /dev/null +++ b/packages/htmldocs/dist/cli/template/documents/templates/Book.tsx @@ -0,0 +1,38 @@ +import { Document, Footer } from "@htmldocs/react" +import MarkdownIt from 'markdown-it' +import fs from 'node:fs' +import path from "path" + +import "~/index.css" + +const content = fs.readFileSync( + path.join(process.env.DOCUMENTS_STATIC_PATH ?? '', 'content.md'), + 'utf-8' +) + +const md = new MarkdownIt({ html: true }) + +function Book() { + const html = md.render(content) + + return ( + +
+
+
+ +