diff --git a/docs/.gitignore b/docs/.gitignore index 843656f..e4841b7 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,23 +1,33 @@ -# Jekyll site files -_site/ -.sass-cache/ -.jekyll-cache/ -.jekyll-metadata -Gemfile.lock -.bundle/ -vendor/ +# deps +/node_modules -# Node/npm -node_modules/ -npm-debug.log -yarn-error.log +# generated content +.contentlayer +.content-collections +.source +auto_apiref/output -# Editor/IDE -.vscode/ -.idea/ -*.swp -*.swo +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo -# OS files +# misc .DS_Store -Thumbs.db +*.pem +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# others +.env*.local +.env +.vercel +next-env.d.ts + +# +fumadocs-basehub \ No newline at end of file diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 2ab17a7..0000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -luats.lol \ No newline at end of file diff --git a/docs/Gemfile b/docs/Gemfile deleted file mode 100644 index 63d786f..0000000 --- a/docs/Gemfile +++ /dev/null @@ -1,13 +0,0 @@ -source "https://rubygems.org" - -gem "jekyll", "~> 4.3.2" -gem "webrick", "~> 1.8" - -group :jekyll_plugins do - gem "jekyll-feed" - gem "jekyll-sitemap" - gem "jekyll-remote-theme" - gem "jekyll-seo-tag" - gem "jekyll-include-cache" - gem "jekyll-redirect-from" -end diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..cc33018 --- /dev/null +++ b/docs/README.md @@ -0,0 +1 @@ +# Docs \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 650e303..0000000 --- a/docs/_config.yml +++ /dev/null @@ -1,84 +0,0 @@ -title: LuaTS -description: A TypeScript library for parsing, formatting, and providing type interfaces for Lua and Luau code -url: https://codemeapixel.github.io/luats -repository: codemeapixel/luats -remote_theme: just-the-docs/just-the-docs - -# Enable plugins -plugins: - - jekyll-feed - - jekyll-sitemap - - jekyll-seo-tag - - jekyll-redirect-from - -# Color scheme settings -color_scheme: dark-code -color_scheme_toggle: true -preferred_color_scheme: dark - -# Available color schemes for the theme toggle -color_schemes: - - name: mellow - label: Mellow - - name: luau - label: Luau - - name: dark-code - label: Dark Code - -# Enable or disable the site search -search_enabled: true - -# Heading anchor links -heading_anchors: true - -# Back to top link -back_to_top: true -back_to_top_text: "Back to top" - -# Footer content -footer_content: "Copyright © 2024-2025 CodeMeAPixel. Distributed under an MIT license." - -# Set a path/url to a logo that will be displayed instead of the title -logo: "/assets/logo.png" - -# Aux links for the upper right navigation -aux_links: - "Luats on GitHub": - - "//github.com/codemeapixel/luats" - -# Makes Aux links open in a new tab -aux_links_new_tab: true - -# Enable callouts -callouts: - note: - title: Note - color: blue - warning: - title: Warning - color: yellow - important: - title: Important - color: red - tip: - title: Tip - color: green - -# For Mermaid diagrams -mermaid: - version: "9.1.3" - -# Optimize for better accessibility -a11y: - skip_to_content: true - nav_buttons: true - -exclude: - - README.md - - node_modules/ - - .sass-cache/ - - .jekyll-cache/ - - gemfiles/ - - Gemfile - - Gemfile.lock - - vendor/ \ No newline at end of file diff --git a/docs/_includes/head_custom.html b/docs/_includes/head_custom.html deleted file mode 100644 index 01b2768..0000000 --- a/docs/_includes/head_custom.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/_sass/color_schemes/dark-code.scss b/docs/_sass/color_schemes/dark-code.scss deleted file mode 100644 index 8ece37a..0000000 --- a/docs/_sass/color_schemes/dark-code.scss +++ /dev/null @@ -1,229 +0,0 @@ -// Dark mode base colors -$dark-000: #0d1117; // GitHub dark background -$dark-100: #161b22; -$dark-200: #21262d; -$dark-300: #30363d; -$dark-400: #484f58; -$dark-500: #6e7681; -$dark-600: #8b949e; -$dark-700: #c9d1d9; -$dark-800: #e6edf3; -$dark-900: #f0f6fc; - -// Accent colors -$accent-blue: #58a6ff; // Primary accent -$accent-green: #3fb950; // Success/string -$accent-yellow: #e3b341; // Warning/number -$accent-orange: #f0883e; // Functions -$accent-red: #f85149; // Error/important -$accent-purple: #bc8cff; // Keywords - -// Assign colors to theme variables - mostly dark by default -$body-background-color: $dark-000; -$body-heading-color: $dark-800; -$body-text-color: $dark-700; -$link-color: $accent-blue; -$btn-primary-color: $accent-blue; -$base-button-color: $dark-200; - -$border-color: $dark-300; -$table-background-color: $dark-100; -$code-background-color: $dark-100; -$search-background-color: $dark-100; -$feedback-color: darken($accent-blue, 3%); - -// Navigation colors -$nav-child-link-color: $dark-600; -$search-result-preview-color: $dark-600; - -// Custom properties for dark code theme -:root { - --dc-primary: #{$accent-blue}; - --dc-secondary: #{$dark-600}; - --dc-accent: #{$accent-orange}; - --dc-text: #{$dark-700}; - --dc-text-light: #{$dark-600}; - --dc-bg: #{$dark-000}; - --dc-bg-card: #{$dark-100}; - --dc-border: #{$dark-300}; - --dc-heading: #{$dark-800}; - --dc-code-bg: #{$dark-100}; - --dc-inline-code-bg: #{rgba($dark-100, 0.7)}; - - // Code syntax highlighting colors - --code-keyword: #{$accent-purple}; - --code-function: #{$accent-orange}; - --code-string: #{$accent-green}; - --code-number: #{$accent-yellow}; - --code-comment: #{$dark-500}; - --code-punctuation: #{$dark-600}; - --code-variable: #{$dark-700}; - --code-operator: #{$accent-red}; - - // Additional UI component colors - --dc-sidebar-bg: #{$dark-100}; - --dc-sidebar-active: #{rgba($dark-200, 0.7)}; - --dc-sidebar-border: #{$dark-300}; - --dc-search-bg: #{rgba($dark-100, 0.8)}; - --dc-search-result-bg: #{$dark-100}; - --dc-nav-link: #{$dark-700}; - --dc-nav-link-active: #{$accent-blue}; - - // By default this theme is dark - background-color: var(--dc-bg); - color: var(--dc-text); -} - -// Light mode overrides -[data-theme='light'] { - --dc-primary: #0969da; - --dc-secondary: #6e7781; - --dc-accent: #953800; - --dc-text: #24292f; - --dc-text-light: #57606a; - --dc-bg: #ffffff; - --dc-bg-card: #f6f8fa; - --dc-border: #d0d7de; - --dc-heading: #24292f; - --dc-code-bg: #f6f8fa; - --dc-inline-code-bg: rgba(175, 184, 193, 0.2); - - // Code syntax highlighting for light mode - --code-keyword: #cf222e; - --code-function: #953800; - --code-string: #0a3622; - --code-number: #953800; - --code-comment: #6e7781; - --code-punctuation: #24292f; - --code-variable: #24292f; - --code-operator: #cf222e; - - // Additional UI component colors for light mode - --dc-sidebar-bg: #f6f8fa; - --dc-sidebar-active: rgba(175, 184, 193, 0.2); - --dc-sidebar-border: #d0d7de; - --dc-search-bg: rgba(175, 184, 193, 0.1); - --dc-search-result-bg: #ffffff; - --dc-nav-link: #24292f; - --dc-nav-link-active: #0969da; - - background-color: var(--dc-bg); - color: var(--dc-text); - - // Light mode styling - code { - background-color: var(--dc-inline-code-bg); - } - - pre.highlight, div.highlighter-rouge { - background-color: var(--dc-code-bg); - border: 1px solid var(--dc-border); - } - - h1, h2, h3, h4, h5, h6 { - color: var(--dc-heading); - } -} - -// Base styles for dark theme -h1, h2, h3, h4, h5, h6 { - color: var(--dc-heading); -} - -a { - color: var(--dc-primary); -} - -code { - background-color: var(--dc-inline-code-bg); - border-radius: 3px; - padding: 0.2em 0.4em; -} - -pre.highlight, div.highlighter-rouge { - background-color: var(--dc-code-bg); - border: 1px solid var(--dc-border); - border-radius: 6px; -} - -// Code syntax highlighting -.highlight { - .k, .kd, .kn, .kp, .kr, .kt { color: var(--code-keyword); } // keywords - .nc, .nf, .nn { color: var(--code-function); } // functions, classes - .s, .s1, .s2, .sr, .se { color: var(--code-string); } // strings - .mi, .mf, .mh, .mo { color: var(--code-number); } // numbers - .c, .c1, .cm, .cp { color: var(--code-comment); } // comments - .p, .o { color: var(--code-punctuation); } // punctuation - .n, .na, .nb, .no { color: var(--code-variable); } // variables - .o, .ow { color: var(--code-operator); } // operators -} - -// Focus styles for accessibility -a:focus, button:focus, [tabindex="0"]:focus { - outline: 2px solid var(--dc-primary); - outline-offset: 2px; -} - -// Table styles -table { - background-color: var(--dc-bg-card); - border: 1px solid var(--dc-border); - - th { - background-color: rgba(175, 184, 193, 0.1); - } - - tr:nth-child(even) { - background-color: rgba(175, 184, 193, 0.05); - } -} - -// Button styles -.btn { - background-color: var(--dc-bg-card); - border: 1px solid var(--dc-border); - - &:hover { - background-color: rgba(175, 184, 193, 0.1); - } -} - -// Primary button styles -.btn-primary { - background-color: var(--dc-primary); - color: white; - - &:hover { - background-color: darken($accent-blue, 5%); - } -} - -// Additional sidebar styling -.side-bar { - background-color: var(--dc-sidebar-bg); - border-right: 1px solid var(--dc-sidebar-border); -} - -.search { - background-color: var(--dc-bg); -} - -.search-input { - background-color: var(--dc-search-bg); - color: var(--dc-text); - border: 1px solid var(--dc-border); -} - -.search-results { - background-color: var(--dc-search-result-bg); -} - -.nav-list .nav-list-item .nav-list-link { - color: var(--dc-text); -} - -.nav-list .nav-list-item .nav-list-link:hover, -.nav-list .nav-list-item .nav-list-link.active { - background-color: var(--dc-sidebar-active); - color: var(--dc-nav-link-active); -} diff --git a/docs/_sass/color_schemes/luau.scss b/docs/_sass/color_schemes/luau.scss deleted file mode 100644 index 75294b6..0000000 --- a/docs/_sass/color_schemes/luau.scss +++ /dev/null @@ -1,421 +0,0 @@ -// Modern Luau-inspired color palette with better contrast and accessibility -$luau-primary-050: #f0f9ff; -$luau-primary-100: #e0f2fe; -$luau-primary-200: #bae6fd; -$luau-primary-300: #7dd3fc; -$luau-primary-400: #38bdf8; -$luau-primary-500: #0ea5e9; // Main Luau blue - more vibrant -$luau-primary-600: #0284c7; -$luau-primary-700: #0369a1; -$luau-primary-800: #075985; -$luau-primary-900: #0c4a6e; - -// Modern orange accent for better harmony -$accent-050: #fff7ed; -$accent-100: #ffedd5; -$accent-200: #fed7aa; -$accent-300: #fdba74; -$accent-400: #fb923c; -$accent-500: #f97316; // Warmer orange -$accent-600: #ea580c; -$accent-700: #c2410c; -$accent-800: #9a3412; -$accent-900: #7c2d12; - -// Enhanced neutrals with better contrast -$neutral-050: #fafafa; -$neutral-100: #f4f4f5; -$neutral-200: #e4e4e7; -$neutral-300: #d4d4d8; -$neutral-400: #a1a1aa; -$neutral-500: #71717a; -$neutral-600: #52525b; -$neutral-700: #3f3f46; -$neutral-800: #27272a; -$neutral-900: #18181b; - -// Success/error colors for better UX -$success-500: #10b981; -$success-600: #059669; -$error-500: #ef4444; -$error-600: #dc2626; -$warning-500: #f59e0b; -$warning-600: #d97706; - -// Assign colors to theme variables with better contrast ratios -$blue-000: $luau-primary-050; -$blue-100: $luau-primary-100; -$blue-200: $luau-primary-200; -$blue-300: $luau-primary-300; - -$link-color: $luau-primary-700; -$btn-primary-color: $luau-primary-600; -$base-button-color: $luau-primary-100; - -$border-color: $luau-primary-200; -$table-background-color: $luau-primary-050; -$code-background-color: $neutral-050; -$search-background-color: $luau-primary-050; - -// Navigation colors with better accessibility -$nav-child-link-color: $luau-primary-700; -$search-result-preview-color: $luau-primary-600; - -// Enhanced CSS custom properties for modern styling -:root { - // Primary brand colors - --luau-primary-50: #{$luau-primary-050}; - --luau-primary-100: #{$luau-primary-100}; - --luau-primary-500: #{$luau-primary-500}; - --luau-primary-600: #{$luau-primary-600}; - --luau-primary-700: #{$luau-primary-700}; - --luau-primary-800: #{$luau-primary-800}; - - // Accent colors - --luau-accent-400: #{$accent-400}; - --luau-accent-500: #{$accent-500}; - --luau-accent-600: #{$accent-600}; - - // Semantic colors - --luau-success: #{$success-500}; - --luau-error: #{$error-500}; - --luau-warning: #{$warning-500}; - - // Text colors with WCAG AA compliance - --luau-text-primary: #{$neutral-900}; - --luau-text-secondary: #{$neutral-700}; - --luau-text-tertiary: #{$neutral-600}; - --luau-text-inverse: #{$neutral-050}; - - // Background colors - --luau-bg-primary: #{$neutral-050}; - --luau-bg-secondary: #{$neutral-100}; - --luau-bg-elevated: #ffffff; - --luau-bg-overlay: #{rgba($neutral-900, 0.8)}; - - // Border colors - --luau-border-light: #{$neutral-200}; - --luau-border-medium: #{$neutral-300}; - --luau-border-strong: #{$neutral-400}; - - // Interactive colors - --luau-interactive-primary: #{$luau-primary-600}; - --luau-interactive-primary-hover: #{$luau-primary-700}; - --luau-interactive-secondary: #{$neutral-200}; - --luau-interactive-secondary-hover: #{$neutral-300}; - - // Code highlighting with modern colors - --code-bg: #{$neutral-050}; - --code-bg-inline: #{rgba($luau-primary-100, 0.4)}; - --code-border: #{$neutral-200}; - --code-keyword: #{$luau-primary-700}; - --code-function: #{$accent-600}; - --code-string: #{$success-600}; - --code-number: #{$accent-500}; - --code-comment: #{$neutral-500}; - --code-punctuation: #{$neutral-600}; - --code-variable: #{$neutral-800}; - - // UI component colors - --luau-sidebar-bg: #{$neutral-050}; - --luau-sidebar-border: #{$neutral-200}; - --luau-sidebar-item-hover: #{rgba($luau-primary-100, 0.6)}; - --luau-sidebar-item-active: #{rgba($luau-primary-200, 0.8)}; - - --luau-nav-link: #{$luau-primary-700}; - --luau-nav-link-hover: #{$luau-primary-800}; - --luau-nav-link-active: #{$luau-primary-800}; - - --luau-search-bg: #{rgba($luau-primary-050, 0.8)}; - --luau-search-border: #{$luau-primary-200}; - --luau-search-focus: #{$luau-primary-500}; - - // Shadows for depth - --luau-shadow-sm: 0 1px 2px 0 #{rgba($neutral-900, 0.05)}; - --luau-shadow-md: 0 4px 6px -1px #{rgba($neutral-900, 0.1)}, 0 2px 4px -1px #{rgba($neutral-900, 0.06)}; - --luau-shadow-lg: 0 10px 15px -3px #{rgba($neutral-900, 0.1)}, 0 4px 6px -2px #{rgba($neutral-900, 0.05)}; - - // Border radius for modern feel - --luau-radius-sm: 0.25rem; - --luau-radius-md: 0.375rem; - --luau-radius-lg: 0.5rem; - --luau-radius-xl: 0.75rem; -} - -// Enhanced dark mode with better contrast and modern colors -[data-theme='dark'] { - // Primary colors adjusted for dark mode - --luau-primary-50: #{$luau-primary-900}; - --luau-primary-100: #{$luau-primary-800}; - --luau-primary-500: #{$luau-primary-400}; - --luau-primary-600: #{$luau-primary-300}; - --luau-primary-700: #{$luau-primary-200}; - --luau-primary-800: #{$luau-primary-100}; - - // Accent colors for dark mode - --luau-accent-400: #{$accent-300}; - --luau-accent-500: #{$accent-400}; - --luau-accent-600: #{$accent-300}; - - // Dark mode text colors - --luau-text-primary: #{$neutral-100}; - --luau-text-secondary: #{$neutral-300}; - --luau-text-tertiary: #{$neutral-400}; - --luau-text-inverse: #{$neutral-900}; - - // Dark mode backgrounds - --luau-bg-primary: #{$neutral-900}; - --luau-bg-secondary: #{$neutral-800}; - --luau-bg-elevated: #{$neutral-800}; - --luau-bg-overlay: #{rgba($neutral-900, 0.9)}; - - // Dark mode borders - --luau-border-light: #{$neutral-700}; - --luau-border-medium: #{$neutral-600}; - --luau-border-strong: #{$neutral-500}; - - // Dark mode interactive colors - --luau-interactive-primary: #{$luau-primary-500}; - --luau-interactive-primary-hover: #{$luau-primary-400}; - --luau-interactive-secondary: #{$neutral-700}; - --luau-interactive-secondary-hover: #{$neutral-600}; - - // Dark mode code colors - --code-bg: #{rgba($neutral-800, 0.6)}; - --code-bg-inline: #{rgba($neutral-700, 0.4)}; - --code-border: #{$neutral-700}; - --code-keyword: #{$luau-primary-300}; - --code-function: #{$accent-300}; - --code-string: #{$success-500}; - --code-number: #{$accent-400}; - --code-comment: #{$neutral-400}; - --code-punctuation: #{$neutral-300}; - --code-variable: #{$neutral-200}; - - // Dark mode UI components - --luau-sidebar-bg: #{$neutral-800}; - --luau-sidebar-border: #{$neutral-700}; - --luau-sidebar-item-hover: #{rgba($luau-primary-800, 0.3)}; - --luau-sidebar-item-active: #{rgba($luau-primary-700, 0.4)}; - - --luau-nav-link: #{$luau-primary-300}; - --luau-nav-link-hover: #{$luau-primary-200}; - --luau-nav-link-active: #{$luau-primary-100}; - - --luau-search-bg: #{rgba($neutral-800, 0.9)}; - --luau-search-border: #{$neutral-600}; - --luau-search-focus: #{$luau-primary-400}; - - background-color: var(--luau-bg-primary) !important; - color: var(--luau-text-primary) !important; - - // Enhanced dark mode styles - code { - background-color: var(--code-bg-inline) !important; - color: var(--luau-text-primary) !important; - border-radius: var(--luau-radius-sm); - } - - pre.highlight, div.highlighter-rouge { - background-color: var(--code-bg) !important; - border: 1px solid var(--code-border); - border-radius: var(--luau-radius-md); - box-shadow: var(--luau-shadow-sm); - } - - h1, h2, h3, h4, h5, h6 { - color: var(--luau-text-primary) !important; - font-weight: 600; - } - - .side-bar { - background-color: var(--luau-sidebar-bg) !important; - border-right: 1px solid var(--luau-sidebar-border) !important; - box-shadow: var(--luau-shadow-md); - } - - .search-input { - background-color: var(--luau-search-bg) !important; - color: var(--luau-text-primary) !important; - border: 1px solid var(--luau-search-border) !important; - border-radius: var(--luau-radius-md); - - &:focus { - border-color: var(--luau-search-focus) !important; - box-shadow: 0 0 0 3px #{rgba($luau-primary-400, 0.1)} !important; - } - } - - .nav-list .nav-list-item .nav-list-link { - color: var(--luau-text-secondary) !important; - border-radius: var(--luau-radius-sm); - transition: all 0.2s ease; - - &:hover { - background-color: var(--luau-sidebar-item-hover) !important; - color: var(--luau-nav-link-hover) !important; - } - - &.active { - background-color: var(--luau-sidebar-item-active) !important; - color: var(--luau-nav-link-active) !important; - font-weight: 500; - } - } -} - -// Enhanced light mode with modern styling -body:not([data-theme='dark']) { - h1, h2, h3, h4, h5, h6 { - color: var(--luau-text-primary); - font-weight: 600; - } - - code { - background-color: var(--code-bg-inline); - color: var(--luau-text-primary); - border-radius: var(--luau-radius-sm); - padding: 0.125rem 0.25rem; - } - - pre.highlight, div.highlighter-rouge { - background-color: var(--code-bg); - border: 1px solid var(--code-border); - border-radius: var(--luau-radius-md); - box-shadow: var(--luau-shadow-sm); - } - - .side-bar { - background-color: var(--luau-sidebar-bg); - border-right: 1px solid var(--luau-sidebar-border); - box-shadow: var(--luau-shadow-md); - } - - .search-input { - background-color: var(--luau-search-bg); - color: var(--luau-text-primary); - border: 1px solid var(--luau-search-border); - border-radius: var(--luau-radius-md); - transition: all 0.2s ease; - - &:focus { - border-color: var(--luau-search-focus); - box-shadow: 0 0 0 3px #{rgba($luau-primary-500, 0.1)}; - } - } - - .nav-list .nav-list-item .nav-list-link { - color: var(--luau-text-secondary); - border-radius: var(--luau-radius-sm); - transition: all 0.2s ease; - - &:hover { - background-color: var(--luau-sidebar-item-hover); - color: var(--luau-nav-link-hover); - } - - &.active { - background-color: var(--luau-sidebar-item-active); - color: var(--luau-nav-link-active); - font-weight: 500; - } - } -} - -// Enhanced syntax highlighting with modern colors -.highlight { - .k, .kd, .kn, .kp, .kr, .kt { color: var(--code-keyword); font-weight: 500; } - .nc, .nf, .nn { color: var(--code-function); font-weight: 500; } - .s, .s1, .s2, .sr, .se { color: var(--code-string); } - .mi, .mf, .mh, .mo { color: var(--code-number); } - .c, .c1, .cm, .cp { color: var(--code-comment); font-style: italic; } - .p, .o { color: var(--code-punctuation); } - .nv, .nb { color: var(--code-variable); } - - // Additional syntax elements - .na { color: var(--luau-accent-600); } // attributes - .nd { color: var(--luau-primary-600); } // decorators - .err { - color: var(--luau-error); - background-color: #{rgba($error-500, 0.1)}; - border-radius: var(--luau-radius-sm); - } -} - -// Modern button styles -.btn { - border-radius: var(--luau-radius-md); - font-weight: 500; - transition: all 0.2s ease; - box-shadow: var(--luau-shadow-sm); - - &:hover { - box-shadow: var(--luau-shadow-md); - transform: translateY(-1px); - } - - &.btn-primary { - background-color: var(--luau-interactive-primary); - - &:hover { - background-color: var(--luau-interactive-primary-hover); - } - } -} - -// Enhanced focus styles for better accessibility -a:focus, -button:focus, -[tabindex="0"]:focus, -.search-input:focus { - outline: 2px solid var(--luau-primary-500); - outline-offset: 2px; - border-radius: var(--luau-radius-sm); -} - -// Improved table styles -table { - border-radius: var(--luau-radius-md); - overflow: hidden; - box-shadow: var(--luau-shadow-sm); - - th { - background-color: var(--luau-primary-50); - color: var(--luau-text-primary); - font-weight: 600; - } - - tr:nth-child(even) { - background-color: var(--luau-bg-secondary); - } - - td, th { - border-color: var(--luau-border-light); - } -} - -// Callout/alert styles -.callout { - border-radius: var(--luau-radius-md); - box-shadow: var(--luau-shadow-sm); - - &.callout-info { - border-left: 4px solid var(--luau-primary-500); - background-color: #{rgba($luau-primary-050, 0.5)}; - } - - &.callout-success { - border-left: 4px solid var(--luau-success); - background-color: #{rgba($success-500, 0.05)}; - } - - &.callout-warning { - border-left: 4px solid var(--luau-warning); - background-color: #{rgba($warning-500, 0.05)}; - } - - &.callout-error { - border-left: 4px solid var(--luau-error); - background-color: #{rgba($error-500, 0.05)}; - } -} diff --git a/docs/_sass/color_schemes/mellow.scss b/docs/_sass/color_schemes/mellow.scss deleted file mode 100644 index a1c5795..0000000 --- a/docs/_sass/color_schemes/mellow.scss +++ /dev/null @@ -1,219 +0,0 @@ -// Purple primary colors (matching Mellow branding) -$purple-000: #f8f6ff; -$purple-100: #e9e4ff; -$purple-200: #d4c8ff; -$purple-300: #b8a7ff; -$purple-400: #9b85ff; -$purple-500: #7c63f0; // Main Mellow purple -$purple-600: #6347e6; -$purple-700: #4a2fd9; -$purple-800: #3219cc; -$purple-900: #1d0dbf; - -// Teal accent colors for contrast -$teal-300: #5eead4; -$teal-500: #14b8a6; -$teal-700: #0f766e; - -// Gray neutrals -$gray-100: #f3f4f6; -$gray-200: #e5e7eb; -$gray-300: #d1d5db; -$gray-700: #374151; -$gray-800: #1f2937; -$gray-900: #111827; - -// Assign colors to theme variables -$blue-000: $purple-000; -$blue-100: $purple-100; -$blue-200: $purple-200; -$blue-300: $purple-300; - -$link-color: $purple-700; // Darker for better contrast -$btn-primary-color: $purple-600; -$base-button-color: $purple-100; - -$border-color: $purple-200; -$table-background-color: $purple-000; -$code-background-color: $purple-000; -$search-background-color: $purple-000; - -// Navigation colors -$nav-child-link-color: $purple-600; -$search-result-preview-color: $purple-500; - -// Custom properties for mental health theme -:root { - --mellow-primary: #{$purple-600}; - --mellow-secondary: #{$purple-300}; - --mellow-accent: #{$teal-500}; - --mellow-accent-light: #{$teal-300}; - --mellow-accent-dark: #{$teal-700}; - --mellow-text: #{$gray-800}; - --mellow-text-light: #{$gray-700}; - --mellow-bg: #{$gray-100}; - --mellow-bg-card: #ffffff; - --mellow-border: #{$purple-200}; - --mellow-heading: #{$purple-800}; - --mellow-code-bg: #{rgba($purple-100, 0.5)}; - --mellow-inline-code-bg: #{rgba($purple-200, 0.3)}; - - // Code syntax highlighting colors - --code-keyword: #{$purple-700}; - --code-function: #{$teal-700}; - --code-string: #16a34a; - --code-number: #f59e0b; - --code-comment: #64748b; - --code-punctuation: #{$gray-700}; - - // Additional UI component colors - --mellow-sidebar-bg: #{$gray-100}; - --mellow-sidebar-active: #{rgba($purple-200, 0.5)}; - --mellow-sidebar-border: #{$purple-100}; - --mellow-search-bg: #{rgba($purple-100, 0.3)}; - --mellow-search-result-bg: #{white}; - --mellow-nav-link: #{$purple-700}; - --mellow-nav-link-active: #{$purple-800}; -} - -// Dark mode overrides -[data-theme='dark'] { - --mellow-primary: #{$purple-300}; // Lighter for better visibility in dark mode - --mellow-secondary: #{$purple-700}; - --mellow-accent: #{$teal-300}; - --mellow-accent-light: #{$teal-500}; - --mellow-accent-dark: #{$teal-700}; - --mellow-text: #{$gray-200}; - --mellow-text-light: #{$gray-300}; - --mellow-bg: #{$gray-900}; - --mellow-bg-card: #{$gray-800}; - --mellow-border: rgba(255, 255, 255, 0.1); - --mellow-heading: #{$purple-200}; - --mellow-code-bg: #{rgba(0, 0, 0, 0.3)}; - --mellow-inline-code-bg: #{rgba(0, 0, 0, 0.2)}; - - // Code syntax highlighting for dark mode - --code-keyword: #{$purple-300}; - --code-function: #{$teal-300}; - --code-string: #86efac; - --code-number: #fbbf24; - --code-comment: #94a3b8; - --code-punctuation: #{$gray-300}; - - // Additional UI component colors for dark mode - --mellow-sidebar-bg: #{$gray-800}; - --mellow-sidebar-active: #{rgba($purple-800, 0.3)}; - --mellow-sidebar-border: #{$gray-700}; - --mellow-search-bg: #{rgba($gray-800, 0.6)}; - --mellow-search-result-bg: #{$gray-800}; - --mellow-nav-link: #{$purple-300}; - --mellow-nav-link-active: #{$purple-200}; - - background-color: var(--mellow-bg) !important; - color: var(--mellow-text) !important; - - // Dark mode code blocks - code { - background-color: var(--mellow-inline-code-bg) !important; - } - - pre.highlight, div.highlighter-rouge { - background-color: var(--mellow-code-bg) !important; - border: 1px solid var(--mellow-border); - } - - // Improve heading contrast in dark mode - h1, h2, h3, h4, h5, h6 { - color: var(--mellow-heading) !important; - } - - // Dark mode sidebar - .side-bar { - background-color: var(--mellow-sidebar-bg) !important; - border-right: 1px solid var(--mellow-sidebar-border) !important; - } - - .search { - background-color: var(--mellow-bg) !important; - } - - .search-input { - background-color: var(--mellow-search-bg) !important; - color: var(--mellow-text) !important; - } - - .search-results { - background-color: var(--mellow-search-result-bg) !important; - } - - .nav-list .nav-list-item .nav-list-link { - color: var(--mellow-text) !important; - } - - .nav-list .nav-list-item .nav-list-link:hover, - .nav-list .nav-list-item .nav-list-link.active { - background-color: var(--mellow-sidebar-active) !important; - color: var(--mellow-nav-link-active) !important; - } -} - -// Light mode improvements -body:not([data-theme='dark']) { - h1, h2, h3, h4, h5, h6 { - color: var(--mellow-heading); - } - - code { - background-color: var(--mellow-inline-code-bg); - } - - pre.highlight, div.highlighter-rouge { - background-color: var(--mellow-code-bg); - border: 1px solid var(--mellow-border); - } - - // Light mode sidebar - .side-bar { - background-color: var(--mellow-sidebar-bg); - border-right: 1px solid var(--mellow-sidebar-border); - } - - .search { - background-color: var(--mellow-bg); - } - - .search-input { - background-color: var(--mellow-search-bg); - color: var(--mellow-text); - } - - .search-results { - background-color: var(--mellow-search-result-bg); - } - - .nav-list .nav-list-item .nav-list-link { - color: var(--mellow-text); - } - - .nav-list .nav-list-item .nav-list-link:hover, - .nav-list .nav-list-item .nav-list-link.active { - background-color: var(--mellow-sidebar-active); - color: var(--mellow-nav-link-active); - } -} - -// Code syntax highlighting -.highlight { - .k, .kd, .kn, .kp, .kr, .kt { color: var(--code-keyword); } // keywords - .nc, .nf, .nn { color: var(--code-function); } // functions, classes - .s, .s1, .s2, .sr, .se { color: var(--code-string); } // strings - .mi, .mf, .mh, .mo { color: var(--code-number); } // numbers - .c, .c1, .cm, .cp { color: var(--code-comment); } // comments - .p, .o { color: var(--code-punctuation); } // punctuation -} - -// Focus styles for accessibility -a:focus, button:focus, [tabindex="0"]:focus { - outline: 2px solid var(--mellow-primary); - outline-offset: 2px; -} diff --git a/docs/api-reference.md b/docs/api-reference.md deleted file mode 100644 index eb6efe4..0000000 --- a/docs/api-reference.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -layout: default -title: API Reference -nav_order: 3 -has_children: true -permalink: /api-reference ---- - -# API Reference -{: .no_toc } - -This section provides detailed documentation for the LuaTS API. -{: .fs-6 .fw-300 } - -LuaTS provides a comprehensive API for parsing, formatting, and type generation. The library is built with a modular architecture that separates concerns across different components. - -## Core Components - -### Parsers -- **[LuaParser](./api-reference/parsers)**: Parse standard Lua code into Abstract Syntax Trees -- **[LuauParser](./api-reference/parsers)**: Parse Luau code with type annotations and modern syntax - -### Clients -- **[LuaFormatter](./api-reference/formatter)**: Format Lua/Luau code with customizable styling -- **[Lexer](./api-reference/lexer)**: Tokenize Lua/Luau code with component-based architecture - -### Generators -- **[TypeGenerator](./api-reference/type-generator)**: Convert Luau types to TypeScript interfaces -- **[MarkdownGenerator](./api-reference/markdown-generator)**: Generate documentation from API definitions - -### Plugin System -- **[Plugin Interface](../plugins)**: Extend and customize type generation -- **Plugin Registry**: Manage multiple plugins -- **File-based Plugin Loading**: Load plugins from JavaScript/TypeScript files - -## Convenience Functions - -These functions provide quick access to common operations: - -```typescript -import { - parseLua, - parseLuau, - formatLua, - generateTypes, - generateTypesWithPlugins, - analyze -} from 'luats'; -``` - -| Function | Description | Returns | -|----------|-------------|---------| -| `parseLua(code)` | Parse Lua code | `AST.Program` | -| `parseLuau(code)` | Parse Luau code with types | `AST.Program` | -| `formatLua(ast)` | Format AST to Lua code | `string` | -| `generateTypes(code, options?)` | Generate TypeScript from Luau | `string` | -| `generateTypesWithPlugins(code, options?, plugins?)` | Generate with plugins | `Promise` | -| `analyze(code, isLuau?)` | Analyze code structure | `AnalysisResult` | - -## Type Definitions - -LuaTS exports comprehensive TypeScript definitions: - -```typescript -import * as AST from 'luats/types'; -import { Token, TokenType } from 'luats/clients/lexer'; -import { TypeGeneratorOptions } from 'luats/generators/typescript'; -import { Plugin } from 'luats/plugins/plugin-system'; -``` - -### Core Types - -- **AST Nodes**: Complete type definitions for Lua/Luau syntax trees -- **Tokens**: Lexical analysis tokens with position information -- **Options**: Configuration interfaces for all components -- **Plugin Interface**: Type-safe plugin development - -## Modular Imports - -You can import specific modules for fine-grained control: - -```typescript -// Parsers -import { LuaParser } from 'luats/parsers/lua'; -import { LuauParser } from 'luats/parsers/luau'; - -// Clients -import { LuaFormatter } from 'luats/clients/formatter'; -import { Lexer } from 'luats/clients/lexer'; - -// Generators -import { TypeGenerator } from 'luats/generators/typescript'; -import { MarkdownGenerator } from 'luats/generators/markdown'; - -// Plugin System -import { loadPlugin, applyPlugins } from 'luats/plugins/plugin-system'; -``` - -## Architecture Overview - -LuaTS uses a modular architecture with clear separation of concerns: - -``` -src/ -├── parsers/ # Code parsing (Lua, Luau) -├── clients/ # Code processing (Lexer, Formatter) -│ └── components/ # Modular lexer components -├── generators/ # Code generation (TypeScript, Markdown) -├── plugins/ # Plugin system and extensions -├── cli/ # Command-line interface -└── types.ts # Core AST type definitions -``` - -### Component Features - -- **Modular Lexer**: Specialized tokenizers for different language constructs -- **Plugin Architecture**: Extensible transformation pipeline -- **Type-Safe APIs**: Full TypeScript support throughout -- **Configuration System**: Flexible options for all components - -## Error Handling - -All components provide comprehensive error handling: - -```typescript -import { ParseError } from 'luats/parsers/lua'; - -try { - const ast = parseLua(invalidCode); -} catch (error) { - if (error instanceof ParseError) { - console.error(`Parse error at ${error.token.line}:${error.token.column}`); - } -} -``` - -## Performance Considerations - -- **Streaming Parsing**: Efficient memory usage for large files -- **Incremental Tokenization**: Process code in chunks -- **Plugin Caching**: Reuse plugin transformations -- **AST Reuse**: Share parsed trees across operations - -For detailed information on each component, see the individual API pages in this section. diff --git a/docs/assets/apple-touch-icon.png b/docs/assets/apple-touch-icon.png deleted file mode 100644 index 98d0a6f..0000000 Binary files a/docs/assets/apple-touch-icon.png and /dev/null differ diff --git a/docs/assets/banner.png b/docs/assets/banner.png deleted file mode 100644 index 4201961..0000000 Binary files a/docs/assets/banner.png and /dev/null differ diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico deleted file mode 100644 index 98d0a6f..0000000 Binary files a/docs/assets/favicon.ico and /dev/null differ diff --git a/docs/assets/logo.png b/docs/assets/logo.png deleted file mode 100644 index dcfc29b..0000000 Binary files a/docs/assets/logo.png and /dev/null differ diff --git a/docs/cli-advanced.md b/docs/cli-advanced.md deleted file mode 100644 index a5bb3e4..0000000 --- a/docs/cli-advanced.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -layout: default -title: CLI Advanced Usage -parent: CLI -nav_order: 2 ---- - -# CLI Advanced Usage - -This guide provides advanced usage patterns and configuration options for the LuaTS CLI. - -## Configuration Options - -### Type Generator Options - -```typescript -interface TypeGeneratorOptions { - // Whether to use 'unknown' type instead of 'any' - useUnknown?: boolean; - - // Prefix to add to generated interfaces - interfacePrefix?: string; - - // Whether to add semicolons to generated code - semicolons?: boolean; - - // Whether to preserve comments from source - preserveComments?: boolean; - - // Whether to generate comments in output - generateComments?: boolean; - - // Style of comments to generate - commentStyle?: 'jsdoc' | 'regular'; -} -``` - -### File Processing - -```typescript -// Process a single file -luats convert src/player.lua -o src/types/player.ts - -// Process a directory with custom pattern -luats dir src/lua --pattern "**/*.luau" -o src/types - -// Exclude specific files -luats dir src/lua --exclude "**/node_modules/**" -o src/types -``` - -### Watch Mode - -```bash -# Watch for changes in a directory -luats dir src/lua -o src/types --watch - -# Watch with verbose output -luats dir src/lua -o src/types --watch --verbose -``` - -## Performance Considerations - -### Batch Processing - -```bash -# Process files in batches -luats dir src/lua -o src/types --batch-size 100 -``` - -### Memory Management - -```bash -# Use memory optimization -luats dir src/lua -o src/types --optimize-memory -``` - -## Error Handling - -### Error Recovery - -```bash -# Continue processing on error -luats dir src/lua -o src/types --continue-on-error - -# Log errors to file -luats dir src/lua -o src/types --error-log errors.log -``` - -## Plugin Integration - -### Using Plugins - -```bash -# Use a plugin -luats convert src/player.lua -o src/types/player.ts --plugin readonly - -# Use multiple plugins -luats convert src/player.lua -o src/types/player.ts --plugin readonly --plugin optimize -``` - -### Plugin Configuration - -```typescript -// Create a plugin config file (plugins.json) -{ - "plugins": [ - { - "name": "readonly", - "options": { - "strict": true - } - }, - { - "name": "optimize", - "options": { - "minify": true - } - } - ] -} -``` - -```bash -# Use plugin config file -luats convert src/player.lua -o src/types/player.ts --plugin-config plugins.json -``` - -## Advanced Features - -### Custom Type Mapping - -```typescript -// Create a custom type mapping file (types.json) -{ - "mappings": { - "Vector2": { - "type": "imported", - "path": "@types/vector2" - }, - "Player": { - "type": "custom", - "interface": { - "id": "string", - "name": "string", - "position": "Vector2" - } - } - } -} -``` - -```bash -# Use custom type mapping -luats convert src/player.lua -o src/types/player.ts --type-mapping types.json -``` - -### Code Generation Hooks - -```typescript -// Create a hook file (hooks.ts) -export const preProcess = (code: string) => { - // Add imports - return `import { Vector2 } from '@types/vector2';\n${code}`; -}; - -export const postProcess = (code: string) => { - // Add exports - return `export { ${code} }`; -}; -``` - -```bash -# Use code generation hooks -luats convert src/player.lua -o src/types/player.ts --hooks hooks.ts -``` - -## Troubleshooting - -### Common Issues - -1. **Type Conversion Errors** - ```bash - # Add type hints - luats convert src/player.lua -o src/types/player.ts --add-type-hints - ``` - -2. **Performance Issues** - ```bash - # Use memory optimization - luats dir src/lua -o src/types --optimize-memory - ``` - -3. **Plugin Errors** - ```bash - # Check plugin compatibility - luats check-plugin my-plugin - ``` - -## Best Practices - -1. **Configuration Management** - ```typescript - // Create a config file (luats.config.json) - { - "typeGenerator": { - "useUnknown": true, - "preserveComments": true - }, - "plugins": [ - "readonly", - "optimize" - ] - } - ``` - -2. **Error Handling** - ```bash - # Always use --continue-on-error in production - luats dir src/lua -o src/types --continue-on-error - ``` - -3. **Performance Optimization** - ```bash - # Use batch processing for large directories - luats dir src/lua -o src/types --batch-size 100 - ``` - -4. **Type Safety** - ```bash - # Use strict type checking - luats convert src/player.lua -o src/types/player.ts --strict-types - ``` diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100644 index 6d5035e..0000000 --- a/docs/cli.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -layout: default -title: CLI -nav_order: 4 ---- - -# CLI Tool -{: .no_toc } - -LuaTS includes a powerful command-line interface for converting Lua/Luau files to TypeScript. -{: .fs-6 .fw-300 } - -## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} - ---- - -## Installation - -The CLI is included with the LuaTS package: - -```bash -# Global installation (optional) -npm install -g luats - -# Or use npx without global installation -npx luats ... -``` - -## Basic Commands - -LuaTS CLI has two main commands: - -1. `convert` - Convert a single file -2. `dir` - Convert all files in a directory - -### Convert a Single File - -```bash -npx luats convert path/to/file.lua -o path/to/output.ts -``` - -### Convert a Directory - -```bash -npx luats dir src/lua -o src/types -``` - -## Command Options - -### Global Options - -These options apply to all commands: - -| Option | Alias | Description | -| --- | --- | --- | -| `--version` | `-V` | Output the version number | -| `--help` | `-h` | Display help information | - -### Convert Command Options - -| Option | Alias | Description | -| --- | --- | --- | -| `--out ` | `-o` | Output file path | -| `--config ` | `-c` | Path to config file | -| `--silent` | `-s` | Suppress output messages | -| `--verbose` | `-v` | Show detailed log information | - -### Directory Command Options - -| Option | Alias | Description | -| --- | --- | --- | -| `--out ` | `-o` | Output directory path | -| `--config ` | `-c` | Path to config file | -| `--silent` | `-s` | Suppress output messages | -| `--verbose` | `-v` | Show detailed log information | -| `--recursive` | `-r` | Process directories recursively | -| `--pattern ` | `-p` | File glob pattern (default: "**/*.{lua,luau}") | -| `--watch` | `-w` | Watch for file changes | - -## Examples - -### Basic Conversion - -Convert a single Lua file to TypeScript: - -```bash -npx luats convert src/player.lua -o src/player.d.ts -``` - -### Directory Conversion - -Convert all Lua files in a directory: - -```bash -npx luats dir src/lua -o src/types -``` - -### Watch Mode - -Automatically convert files when they change: - -```bash -npx luats dir src/lua -o src/types --watch -``` - -### Custom Pattern - -Only convert files matching a specific pattern: - -```bash -npx luats dir src -o types --pattern "**/*.luau" -``` - -### Using a Config File - -Use a configuration file for consistent options: - -```bash -npx luats dir src -o types --config luats.config.json -``` - -## Configuration File - -You can use a configuration file to specify options for the CLI. The file can be in JSON format and should be named `luats.config.json` (default) or `.luatsrc.json`. - -Example configuration file: - -```json -{ - "outDir": "./types", - "include": ["**/*.lua", "**/*.luau"], - "exclude": ["**/node_modules/**", "**/dist/**"], - "preserveDirectoryStructure": true, - "plugins": ["./plugins/my-plugin.js"], - "preserveComments": true, - "commentStyle": "jsdoc", - "inferTypes": false, - "mergeInterfaces": true, - "typeGeneratorOptions": { - "useUnknown": true, - "exportTypes": true, - "useReadonly": false, - "generateComments": true, - "arrayType": "auto", - "preserveTableIndexSignatures": true, - "functionStyle": "arrow", - "indentSpaces": 2, - "singleQuote": true, - "trailingComma": false - } -} -``` - -## Error Handling - -The CLI provides helpful error messages for common issues: - -- Syntax errors in Lua/Luau files -- File not found errors -- Permission issues -- Configuration errors - -For detailed error information, use the `--verbose` flag: - -```bash -npx luats convert file.lua -o file.d.ts --verbose -``` - -## Exit Codes - -| Code | Description | -| --- | --- | -| 0 | Success | -| 1 | Error (file not found, parse error, etc.) | - -## Integrating with Build Tools - -### npm scripts - -You can add LuaTS to your build process using npm scripts: - -```json -{ - "scripts": { - "build:types": "luats dir src/lua -o src/types", - "watch:types": "luats dir src/lua -o src/types --watch", - "prebuild": "npm run build:types" - } -} -``` - -### GitHub Actions - -Example GitHub Action workflow: - -```yaml -name: Generate TypeScript Definitions - -on: - push: - paths: - - '**/*.lua' - - '**/*.luau' - -jobs: - generate-types: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: '16' - - run: npm install -g luats - - run: luats dir src/lua -o src/types - - name: Commit changes - uses: EndBug/add-and-commit@v7 - with: - message: 'Update TypeScript definitions' - add: 'src/types' -``` diff --git a/docs/api-reference/api-usage.md b/docs/content/docs/api-refrence/api-usage.mdx similarity index 95% rename from docs/api-reference/api-usage.md rename to docs/content/docs/api-refrence/api-usage.mdx index c97a541..05cb6c5 100644 --- a/docs/api-reference/api-usage.md +++ b/docs/content/docs/api-refrence/api-usage.mdx @@ -1,13 +1,11 @@ --- -layout: default title: API Usage -parent: API Reference -nav_order: 1 +icon: TbApi +description: This guide provides comprehensive examples and best practices for using the LuaTS API. --- -# API Usage Guide - -This guide provides comprehensive examples and best practices for using the LuaTS API. +## Table of contents + ## Basic Usage @@ -252,4 +250,4 @@ for (let i = 0; i < files.length; i += batchSize) { } type Account = User | Admin; - ``` + ``` \ No newline at end of file diff --git a/docs/api-reference/ast-types.md b/docs/content/docs/api-refrence/ast-types.mdx similarity index 99% rename from docs/api-reference/ast-types.md rename to docs/content/docs/api-refrence/ast-types.mdx index cf1a488..e536897 100644 --- a/docs/api-reference/ast-types.md +++ b/docs/content/docs/api-refrence/ast-types.mdx @@ -1,12 +1,10 @@ --- -layout: default title: AST Types -parent: API Reference -nav_order: 4 +icon: BsBracesAsterisk --- -# AST Types -{: .no_toc } +## Table of contents + This page documents the Abstract Syntax Tree (AST) types used in LuaTS. {: .fs-6 .fw-300 } diff --git a/docs/api-reference/formatter.md b/docs/content/docs/api-refrence/formatter.mdx similarity index 73% rename from docs/api-reference/formatter.md rename to docs/content/docs/api-refrence/formatter.mdx index 062a2da..55cbb59 100644 --- a/docs/api-reference/formatter.md +++ b/docs/content/docs/api-refrence/formatter.mdx @@ -1,21 +1,14 @@ --- -layout: default title: Formatter -parent: API Reference -nav_order: 3 +icon: IoInformation --- -# Formatter -{: .no_toc } The `LuaFormatter` class provides functionality to format Lua/Luau ASTs back into properly formatted code. {: .fs-6 .fw-300 } ## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} + --- @@ -57,16 +50,50 @@ console.log(formattedCode); The `LuaFormatter` constructor accepts an options object with the following properties: -| Option | Type | Default | Description | -| --- | --- | --- | --- | -| `indentSize` | number | `2` | Number of spaces for indentation | -| `useTabs` | boolean | `false` | Use tabs instead of spaces for indentation | -| `maxLineLength` | number | `80` | Maximum characters per line | -| `insertFinalNewline` | boolean | `true` | Add a newline at the end of the file | -| `trimTrailingWhitespace` | boolean | `true` | Remove trailing whitespace | -| `insertSpaceAfterComma` | boolean | `true` | Add space after commas | -| `insertSpaceAroundOperators` | boolean | `true` | Add spaces around operators | -| `insertSpaceAfterKeywords` | boolean | `true` | Add space after keywords | + You can get the default options with: @@ -161,4 +188,4 @@ The formatter aims to follow common Lua style guides by default, including: - Line breaks between statements and blocks - Proper alignment of table fields and function parameters -You can customize these settings through the formatter options to match your project's style guide. +You can customize these settings through the formatter options to match your project's style guide. \ No newline at end of file diff --git a/docs/api-reference/lexer.md b/docs/content/docs/api-refrence/lexer.mdx similarity index 95% rename from docs/api-reference/lexer.md rename to docs/content/docs/api-refrence/lexer.mdx index 999c5a8..ad97c78 100644 --- a/docs/api-reference/lexer.md +++ b/docs/content/docs/api-refrence/lexer.mdx @@ -1,21 +1,11 @@ --- -layout: default title: Lexer Architecture -parent: API Reference -nav_order: 6 +icon: MdArchitecture +description: Understanding LuaTS's modular lexer system and its component-based architecture. --- -# Lexer Architecture -{: .no_toc } - -Understanding LuaTS's modular lexer system and its component-based architecture. -{: .fs-6 .fw-300 } - ## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} + --- @@ -27,15 +17,19 @@ LuaTS features a sophisticated modular lexer system built with a component-based ### Component Structure -``` -src/clients/ -├── lexer.ts # Main lexer re-export -└── components/ - ├── lexer.ts # Core lexer implementation - ├── tokenizers.ts # Specialized tokenizers - ├── operators.ts # Operator definitions - └── types.ts # Token type definitions -``` + + + + + + + + + + + + + ### Design Principles @@ -597,4 +591,4 @@ try { - **Custom operator support**: Allow plugins to define new operators - **Performance profiling**: Built-in tokenization performance metrics -The modular lexer architecture makes LuaTS both powerful and extensible, providing a solid foundation for parsing Lua and Luau code while remaining maintainable and performant. +The modular lexer architecture makes LuaTS both powerful and extensible, providing a solid foundation for parsing Lua and Luau code while remaining maintainable and performant. \ No newline at end of file diff --git a/docs/api-reference/markdown-generator.md b/docs/content/docs/api-refrence/markdown-generator.mdx similarity index 97% rename from docs/api-reference/markdown-generator.md rename to docs/content/docs/api-refrence/markdown-generator.mdx index 46e3925..f43c494 100644 --- a/docs/api-reference/markdown-generator.md +++ b/docs/content/docs/api-refrence/markdown-generator.mdx @@ -1,8 +1,6 @@ --- -layout: default title: Markdown Generator -parent: API Reference -nav_order: 2 +icon: FaMarkdown --- # MarkdownGenerator API @@ -125,4 +123,4 @@ The generated Markdown includes: ## See Also - [Type Generator](./type-generator) -- [API Reference](./api-reference) +- [API Reference](./api-reference) \ No newline at end of file diff --git a/docs/content/docs/api-refrence/meta.json b/docs/content/docs/api-refrence/meta.json new file mode 100644 index 0000000..f279a96 --- /dev/null +++ b/docs/content/docs/api-refrence/meta.json @@ -0,0 +1,15 @@ +{ + "title": "API-Refrence", + "description": "API level knowledge for using LuaTS", + "icon": "TbApi", + "root": true, + "pages": [ + "api-usage", + "ast-type", + "formatter", + "lexer", + "markdown-generator", + "prasers", + "type-generator" + ] +} diff --git a/docs/api-reference/parsers.md b/docs/content/docs/api-refrence/parsers.mdx similarity index 90% rename from docs/api-reference/parsers.md rename to docs/content/docs/api-refrence/parsers.mdx index 2d82bca..94361f6 100644 --- a/docs/api-reference/parsers.md +++ b/docs/content/docs/api-refrence/parsers.mdx @@ -1,21 +1,11 @@ --- -layout: default title: Parsers -parent: API Reference -nav_order: 1 +description: The parser classes in LuaTS are responsible for converting Lua/Luau code into an Abstract Syntax Tree (AST). --- -# Parsers -{: .no_toc } - -The parser classes in LuaTS are responsible for converting Lua/Luau code into an Abstract Syntax Tree (AST). -{: .fs-6 .fw-300 } ## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} + --- @@ -139,4 +129,4 @@ const luauAst = parseLuau(` The AST generated by the parsers follows a structure similar to the Lua/Luau language specification. -See the [AST Types](./ast-types) documentation for detailed information on the structure. +See the [AST Types](./ast-types) documentation for detailed information on the structure. \ No newline at end of file diff --git a/docs/api-reference/type-generator.md b/docs/content/docs/api-refrence/type-generator.mdx similarity index 97% rename from docs/api-reference/type-generator.md rename to docs/content/docs/api-refrence/type-generator.mdx index af43fbe..b54e842 100644 --- a/docs/api-reference/type-generator.md +++ b/docs/content/docs/api-refrence/type-generator.mdx @@ -1,21 +1,11 @@ --- -layout: default title: Type Generator -parent: API Reference -nav_order: 5 --- -# Type Generator -{: .no_toc } - The `TypeGenerator` class is responsible for converting Luau type definitions into TypeScript interfaces. -{: .fs-6 .fw-300 } ## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} + --- @@ -220,4 +210,4 @@ const tsCodeWithPlugins = await generateTypesWithPlugins( ); ``` -See the [Plugin System](../plugins) documentation for more details. +See the [Plugin System](../plugins) documentation for more details. \ No newline at end of file diff --git a/docs/content/docs/meta.json b/docs/content/docs/meta.json new file mode 100644 index 0000000..e5590bf --- /dev/null +++ b/docs/content/docs/meta.json @@ -0,0 +1,3 @@ +{ + "pages": ["user", "api-refrence", "plugins"] +} diff --git a/docs/plugins-advanced.md b/docs/content/docs/plugins/advanced.mdx similarity index 99% rename from docs/plugins-advanced.md rename to docs/content/docs/plugins/advanced.mdx index 4348fc3..4b563df 100644 --- a/docs/plugins-advanced.md +++ b/docs/content/docs/plugins/advanced.mdx @@ -1,8 +1,5 @@ --- -layout: default title: Plugin System Advanced -parent: Plugin System -nav_order: 2 --- # Plugin System Advanced @@ -312,4 +309,4 @@ const CombinedPlugin: Plugin = { start: () => {}, stop: () => {} }; - ``` + ``` \ No newline at end of file diff --git a/docs/plugins.md b/docs/content/docs/plugins/index.mdx similarity index 98% rename from docs/plugins.md rename to docs/content/docs/plugins/index.mdx index b86a8f2..20c5ab9 100644 --- a/docs/plugins.md +++ b/docs/content/docs/plugins/index.mdx @@ -1,20 +1,13 @@ --- -layout: default title: Plugin System -nav_order: 5 --- # Plugin System -{: .no_toc } LuaTS provides a comprehensive plugin system that allows you to customize and extend the type generation process. -{: .fs-6 .fw-300 } ## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} + --- @@ -379,4 +372,4 @@ LuaTS plugins can be shared and distributed: } ``` -This enables a rich ecosystem of community plugins for specialized use cases. +This enables a rich ecosystem of community plugins for specialized use cases. \ No newline at end of file diff --git a/docs/content/docs/plugins/meta.json b/docs/content/docs/plugins/meta.json new file mode 100644 index 0000000..0570011 --- /dev/null +++ b/docs/content/docs/plugins/meta.json @@ -0,0 +1,6 @@ +{ + "icon": "BsPlugin", + "title": "Plugins", + "root": true, + "pages": ["advanced"] +} \ No newline at end of file diff --git a/docs/contributing.md b/docs/content/docs/user/contribution.mdx similarity index 87% rename from docs/contributing.md rename to docs/content/docs/user/contribution.mdx index ba6fbc0..92e3032 100644 --- a/docs/contributing.md +++ b/docs/content/docs/user/contribution.mdx @@ -1,20 +1,16 @@ --- -layout: default title: Contributing -nav_order: 7 +description: Contribution guide +icon: FaHandshake --- # Contributing to LuaTS -{: .no_toc } This guide will help you contribute to the LuaTS project. -{: .fs-6 .fw-300 } ## Table of contents -{: .no_toc .text-delta } + -1. TOC -{:toc} --- @@ -47,28 +43,34 @@ This guide will help you contribute to the LuaTS project. Understanding LuaTS's modular architecture is crucial for contributing effectively: -``` -src/ -├── parsers/ # Code parsing (Lua, Luau) -│ ├── lua.ts # Standard Lua parser -│ └── luau.ts # Luau parser with type support -├── clients/ # Code processing and analysis -│ ├── components/ # Modular lexer components -│ │ ├── lexer.ts # Main lexer implementation -│ │ ├── tokenizers.ts # Specialized tokenizers -│ │ ├── operators.ts # Operator definitions -│ │ └── types.ts # Token type definitions -│ ├── lexer.ts # Lexer re-export for compatibility -│ └── formatter.ts # Code formatting -├── generators/ # Code generation -│ ├── typescript/ # TypeScript generator -│ └── markdown/ # Documentation generator -├── plugins/ # Plugin system -│ └── plugin-system.ts # Plugin architecture -├── cli/ # Command-line interface -├── types.ts # Core AST type definitions -└── index.ts # Main library exports -``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + ### Key Components @@ -370,4 +372,4 @@ For maintainers preparing releases: 4. **Build and test distribution** 5. **Tag release** and publish -Thank you for contributing to LuaTS! Your contributions help improve the Lua/TypeScript development experience for everyone. +Thank you for contributing to LuaTS! Your contributions help improve the Lua/TypeScript development experience for everyone. \ No newline at end of file diff --git a/docs/examples.md b/docs/content/docs/user/examples.mdx similarity index 98% rename from docs/examples.md rename to docs/content/docs/user/examples.mdx index 9dff062..f51d904 100644 --- a/docs/examples.md +++ b/docs/content/docs/user/examples.mdx @@ -1,20 +1,16 @@ --- -layout: default title: Examples -nav_order: 6 +descrption: This page provides various examples of using LuaTS in different scenarios. +icon: MdOutlineDeveloperBoard --- # Examples -{: .no_toc } This page provides various examples of using LuaTS in different scenarios. -{: .fs-6 .fw-300 } ## Table of contents -{: .no_toc .text-delta } + -1. TOC -{:toc} --- @@ -607,4 +603,4 @@ describe('Type Generation', () => { }); ``` -These examples demonstrate the full power and flexibility of LuaTS, from basic type conversion to advanced plugin development and integration scenarios. +These examples demonstrate the full power and flexibility of LuaTS, from basic type conversion to advanced plugin development and integration scenarios. \ No newline at end of file diff --git a/docs/content/docs/user/index.mdx b/docs/content/docs/user/index.mdx new file mode 100644 index 0000000..d727c7e --- /dev/null +++ b/docs/content/docs/user/index.mdx @@ -0,0 +1,184 @@ +--- +title: LuaTS - TypeScript Library for Lua/Luau +description: A powerful TypeScript library for parsing, formatting, and providing type interfaces for Lua and Luau code. +icon: FaHome +--- + + + LuaTS bridges the gap between Lua/Luau and TypeScript, enabling seamless type conversion and powerful tooling for modern development workflows. + + +## Overview + +LuaTS is a comprehensive library designed for developers working with Lua/Luau code in TypeScript environments. It provides robust parsing, formatting, and type conversion capabilities that make cross-language development smooth and efficient. + + + + + + + + +## Key Features + +### Core Functionality + +- **🔁 Type Declaration Conversion**: Seamlessly converts Lua/Luau type declarations into TypeScript interfaces +- **🧠 Intelligent Type Mapping**: Maps Lua primitive types (`string`, `number`, `boolean`) to TypeScript equivalents +- **❓ Optional Type Support**: Handles optional types (`foo: string?` → `foo?: string`) with proper nullability +- **🔧 Advanced Table Handling**: Converts table types (`{string}` → `string[]` or `Record`) +- **➡️ Function Type Conversion**: Transforms Luau function types to TypeScript arrow functions +- **📄 Comment Preservation**: Maintains comments and converts them to JSDoc format + +### Developer Experience + +- **📁 Flexible Processing**: Single-file or batch directory conversion support +- **🛠 Comprehensive CLI**: Feature-rich command-line interface with extensive options +- **🧪 Syntax Validation**: Built-in syntax validation with detailed error reporting +- **🔌 Plugin System**: Extensible architecture with custom transform hooks +- **🔄 Type Merging**: Intelligent handling of overlapping types and shared structures +- **📦 Programmatic API**: Full-featured API for programmatic usage + +## Quick Start + + + + ### Installation + + Install LuaTS using your preferred package manager: + + ```bash + npm install luats + # or + yarn add luats + # or + bun add luats + ``` + + + + ### Basic Usage + + Import and use LuaTS in your TypeScript project: + + ```typescript + import { generateTypes } from 'luats'; + + const luaCode = ` + type Vector3 = { + x: number, + y: number, + z: number + } + + type Player = { + name: string, + position: Vector3, + health: number? + } + `; + + const tsCode = generateTypes(luaCode); + console.log(tsCode); + ``` + + + The generated TypeScript code maintains full type safety while preserving the original structure and semantics. + + + + + ### CLI Usage + + Use the command-line interface for quick conversions: + + ```bash + # Convert a single file + luats convert input.lua --output output.d.ts + + # Process an entire directory + luats convert src/ --output types/ --recursive + + # Use with configuration file + luats convert --config luats.config.json + ``` + + + + +## Performance & Benchmarks + + + LuaTS is optimized for performance with efficient parsing algorithms and minimal memory footprint. + + + + + + + + +LuaTS is used by developers across various domains: + +- **Game Development**: Converting Roblox/Luau game scripts to TypeScript +- **Embedded Systems**: Type-safe interfaces for Lua-based embedded applications +- **DevOps**: Configuration management with type safety +- **Web Development**: Lua template engines with TypeScript integration + +The complete API provides programmatic access to all LuaTS functionality: + +## Community & Support + + + + + + + +## License + + + LuaTS is distributed under the [MIT License](https://github.com/codemeapixel/luats/blob/master/LICENSE). + Feel free to use it in your projects, both commercial and open source. + + +--- + +Ready to get started? [Install LuaTS](/docs/installation) today and transform your Lua/Luau development workflow! \ No newline at end of file diff --git a/docs/content/docs/user/meta.json b/docs/content/docs/user/meta.json new file mode 100644 index 0000000..5c8a9b7 --- /dev/null +++ b/docs/content/docs/user/meta.json @@ -0,0 +1,12 @@ +{ + "title": "User Guide", + "description": "Basic knowledge for using LuaTS", + "icon": "User", + "root": true, + "pages": [ + "testing", + "contribution", + "examples", + "type-system" + ] +} diff --git a/docs/testing.md b/docs/content/docs/user/testing.mdx similarity index 97% rename from docs/testing.md rename to docs/content/docs/user/testing.mdx index 29e8d56..71c1041 100644 --- a/docs/testing.md +++ b/docs/content/docs/user/testing.mdx @@ -1,7 +1,7 @@ --- -layout: default title: Testing -nav_order: 7 +descrption: testing guide for LuaTS +icon: FaScrewdriverWrench --- # Testing Guide @@ -180,4 +180,4 @@ npm run test:update test/snapshots.test.ts - Add benchmark tests - Measure memory usage - Test with large inputs - - Verify edge cases + - Verify edge cases \ No newline at end of file diff --git a/docs/type-system.md b/docs/content/docs/user/type-system.mdx similarity index 94% rename from docs/type-system.md rename to docs/content/docs/user/type-system.mdx index f41755e..972e8d9 100644 --- a/docs/type-system.md +++ b/docs/content/docs/user/type-system.mdx @@ -1,12 +1,11 @@ --- -layout: default title: Type System -nav_order: 3 +description: This guide explains how the LuaTS type system works and how to effectively use it for type conversion. +icon: MdMergeType --- -# Type System - -This guide explains how the LuaTS type system works and how to effectively use it for type conversion. +## Table of contents + ## Type Conversion Rules @@ -265,4 +264,4 @@ type Account = User | Admin; interface Deep { level1: Level1; } - ``` + ``` \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index a4b393c..0000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,334 +0,0 @@ ---- -layout: default -title: Getting Started -nav_order: 2 ---- - -# Getting Started -{: .no_toc } - -This guide will help you get started with LuaTS quickly. -{: .fs-6 .fw-300 } - -## Table of contents -{: .no_toc .text-delta } - -1. TOC -{:toc} - ---- - -## Installation - -LuaTS can be installed using your preferred package manager: - -```bash -# Using bun (recommended for development) -bun add luats - -# Using npm -npm install luats - -# Using yarn -yarn add luats -``` - -## Basic Usage - -### Parsing Lua Code - -```typescript -import { parseLua } from 'luats'; -// or import the class directly -import { LuaParser } from 'luats/parsers/lua'; - -// Using convenience function -const ast = parseLua(` - local function greet(name) - return "Hello, " .. name - end - - print(greet("World")) -`); - -console.log(ast); -``` - -### Parsing Luau Code (with Types) - -```typescript -import { parseLuau } from 'luats'; -// or import the class directly -import { LuauParser } from 'luats/parsers/luau'; - -// Parse Luau code with type annotations -const ast = parseLuau(` - type Person = { - name: string, - age: number, - active?: boolean - } - - local function createPerson(name: string, age: number): Person - return { - name = name, - age = age, - active = true - } - end -`); - -console.log(ast); -``` - -### Generating TypeScript from Luau Types - -```typescript -import { generateTypes } from 'luats'; - -const luauCode = ` - type Vector3 = { - x: number, - y: number, - z: number - } - - type Player = { - name: string, - position: Vector3, - health: number, - inventory: {string}, -- Array of strings - metadata?: {[string]: any}, -- Optional record - greet: (self: Player, message: string) -> string -- Method - } - - type GameEvent = "PlayerJoined" | "PlayerLeft" | "PlayerMoved" -`; - -const tsCode = generateTypes(luauCode, { - useUnknown: true, - includeSemicolons: true, - interfacePrefix: 'I' -}); - -console.log(tsCode); -``` - -**Output:** -```typescript -interface IVector3 { - x: number; - y: number; - z: number; -} - -interface IPlayer { - name: string; - position: IVector3; - health: number; - inventory: string[]; - metadata?: Record; - greet: (message: string) => string; // self parameter removed -} - -type GameEvent = "PlayerJoined" | "PlayerLeft" | "PlayerMoved"; -``` - -### Formatting Lua Code - -```typescript -import { formatLua } from 'luats'; -import { LuaFormatter } from 'luats/clients/formatter'; - -// Using convenience function -const messyCode = `local x=1+2 local y=x*3 if x>5 then print("big") end`; -const formatted = formatLua(messyCode); - -// Using class with custom options -const formatter = new LuaFormatter({ - indentSize: 4, - insertSpaceAroundOperators: true, - insertSpaceAfterComma: true, - maxLineLength: 100 -}); - -const customFormatted = formatter.format(messyCode); -``` - -### Working with the Lexer - -```typescript -import { Lexer, TokenType } from 'luats/clients/lexer'; - -const lexer = new Lexer(` - local name: string = "World" - print("Hello, " .. name) -`); - -const tokens = lexer.tokenize(); -tokens.forEach(token => { - console.log(`${token.type}: "${token.value}" at ${token.line}:${token.column}`); -}); -``` - -## Advanced Usage - -### Using Plugins - -```typescript -import { generateTypesWithPlugins } from 'luats'; - -// Create a custom plugin -const readonlyPlugin = { - name: 'ReadonlyPlugin', - description: 'Makes all properties readonly', - postProcess: (code) => { - return code.replace(/^(\s*)([a-zA-Z_]\w*)(\??):\s*(.+);$/gm, - '$1readonly $2$3: $4;'); - } -}; - -const tsCode = await generateTypesWithPlugins( - luauCode, - { useUnknown: true }, - [readonlyPlugin] -); -``` - -### Analyzing Code - -```typescript -import { analyze } from 'luats'; - -const result = analyze(` - type User = { - name: string, - age: number - } - - local function createUser(name: string, age: number): User - return { name = name, age = age } - end -`, true); // true for Luau analysis - -console.log(`Errors: ${result.errors.length}`); -console.log(`AST nodes: ${result.ast.body.length}`); -if (result.types) { - console.log('Generated types:', result.types); -} -``` - -## Using the CLI - -### Basic Commands - -```bash -# Convert a single file -npx luats convert src/types.lua -o src/types.d.ts - -# Convert all files in a directory -npx luats convert-dir src/lua -o src/types - -# Validate syntax -npx luats validate src/types.lua - -# Show help -npx luats --help -``` - -### Watch Mode - -```bash -# Watch for changes and auto-convert -npx luats convert-dir src/lua -o src/types --watch -``` - -### Using Configuration - -Create `luats.config.json`: - -```json -{ - "outDir": "./types", - "include": ["**/*.lua", "**/*.luau"], - "exclude": ["**/node_modules/**", "**/dist/**"], - "preserveComments": true, - "commentStyle": "jsdoc", - "typeGeneratorOptions": { - "useUnknown": true, - "interfacePrefix": "I", - "includeSemicolons": true - }, - "plugins": [] -} -``` - -Then run: - -```bash -npx luats convert-dir src/lua --config luats.config.json -``` - -## Examples - -### Roblox Development - -```lua --- player.luau -type Vector3 = { - X: number, - Y: number, - Z: number -} - -type Player = { - Name: string, - UserId: number, - Character: Model?, - Position: Vector3, - TeamColor: BrickColor -} - -export type PlayerData = { - player: Player, - stats: {[string]: number}, - inventory: {[string]: number} -} -``` - -Convert to TypeScript: - -```bash -npx luats convert player.luau -o player.d.ts -``` - -Generated TypeScript: - -```typescript -interface Vector3 { - X: number; - Y: number; - Z: number; -} - -interface Player { - Name: string; - UserId: number; - Character?: Model; - Position: Vector3; - TeamColor: BrickColor; -} - -export interface PlayerData { - player: Player; - stats: Record; - inventory: Record; -} -``` - -## Next Steps - -- Explore the [CLI Documentation](./cli) for advanced command-line usage -- Check out the [API Reference](./api-reference) for detailed documentation -- Learn about the [Plugin System](./plugins) for custom transformations -- Browse [Examples](./examples) for real-world usage patterns diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 4595ef6..0000000 --- a/docs/index.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -layout: home -title: Home -nav_order: 1 -permalink: / ---- - -# LuaTS -{: .fs-9 } - -A TypeScript library for parsing, formatting, and providing type interfaces for Lua and Luau code. -{: .fs-6 .fw-300 } - -[Get Started](./getting-started){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } -[View on GitHub](https://github.com/codemeapixel/luats){: .btn .fs-5 .mb-4 .mb-md-0 } - ---- - -## Overview - -LuaTS is a powerful library for converting Lua/Luau type annotations into TypeScript interfaces. It provides robust tooling for developers working with Lua/Luau code in TypeScript environments. - -## Features - -- 🔁 **Converts Lua/Luau type declarations into TypeScript interfaces** -- 🧠 **Maps Lua types to TypeScript equivalents** (`string`, `number`, etc.) -- ❓ **Supports optional types** (`foo: string?` → `foo?: string`) -- 🔧 **Handles table types** (`{string}` → `string[]` or `Record`) -- ➡️ **Converts Luau function types to arrow functions in TS** -- 📄 **Preserves comments and maps them to JSDoc format** -- 📁 **Supports single-file or batch directory conversion** -- 🛠 **Includes a CLI tool** with various options -- 🧪 **Validates syntax and reports conversion errors** -- 🔌 **Optional config file** (`luats.config.json`) -- 🔄 **Merges overlapping types or handles shared structures** -- 📦 **Programmatic API** with comprehensive options -- 🧩 **Plugin hook system for custom transforms** -- 🧠 **Optional inference for inline tables** -- 📜 **Fully typed** (written in TypeScript) - -## Quick Example - -```typescript -import { generateTypes } from 'luats'; - -const tsCode = generateTypes(` - type Vector3 = { - x: number, - y: number, - z: number - } -`); - -console.log(tsCode); -// Output: -// interface Vector3 { -// x: number; -// y: number; -// z: number; -// } -``` - -## License - -LuaTS is distributed under the [MIT license](https://github.com/codemeapixel/luats/blob/master/LICENSE). diff --git a/docs/next.config.ts b/docs/next.config.ts new file mode 100644 index 0000000..e65eb52 --- /dev/null +++ b/docs/next.config.ts @@ -0,0 +1,30 @@ +/** @type {import('next').NextConfig} */ +import { createMDX } from "fumadocs-mdx/next"; + +const withMDX = createMDX(); + +const config = { + typescript: { + ignoreBuildErrors: true, + }, + reactStrictMode: true, + env: { + NEXT_PUBLIC_BUILD_ENV: process.env.NODE_ENV || "development", + }, + serverExternalPackages: ["shiki"], + images: { + remotePatterns: [ + { + hostname: "**", + }, + ], + }, + experimental: { + mdxRs: true, + }, + assetPrefix: + process.env.NODE_ENV === "production" ? "https://luats.lol" : "", + basePath: process.env.NODE_ENV === "production" ? "" : "", +}; + +export default withMDX(config); diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000..8c57e5f --- /dev/null +++ b/docs/package.json @@ -0,0 +1,96 @@ +{ + "name": "luats", + "version": "2.0.0", + "private": true, + "author": "Ranveer Soni ", + "scripts": { + "build": "next build", + "dev": "next dev --turbopack", + "format": "prettier --write .", + "start": "next start", + "postinstall": "fumadocs-mdx" + }, + "dependencies": { + "@ai-sdk/openai": "^1.3.22", + "@ai-sdk/react": "^1.2.12", + "@fumadocs/mdx-remote": "^1.3.3", + "@next/bundle-analyzer": "^15.3.4", + "@radix-ui/react-collapsible": "^1.1.11", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-hover-card": "^1.1.14", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tooltip": "^1.2.7", + "@shikijs/rehype": "^3.7.0", + "ajv": "^8.17.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "framer-motion": "^12.23.5", + "fumadocs-core": "15.5.4", + "fumadocs-docgen": "^2.0.1", + "fumadocs-mdx": "11.6.9", + "fumadocs-openapi": "^9.1.2", + "fumadocs-twoslash": "^3.1.4", + "fumadocs-typescript": "^4.0.6", + "fumadocs-ui": "^15.6.3", + "hast-util-to-jsx-runtime": "^2.3.6", + "katex": "^0.16.22", + "lucide-react": "^0.522.0", + "mermaid": "^11.7.0", + "motion": "^12.18.1", + "next": "15.3.4", + "oxc-transform": "^0.56.5", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-error-boundary": "^6.0.0", + "react-icons": "^5.5.0", + "rehype-katex": "^7.0.1", + "remark": "^15.0.1", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0", + "remark-mdx": "^3.1.0", + "remark-rehype": "^11.1.2", + "remark-stringify": "^11.0.0", + "rimraf": "^6.0.1", + "shiki": "^3.7.0", + "tailwind-merge": "^3.3.1", + "tw-animate-css": "^1.3.4", + "twoslash": "0.3.1" + }, + "devDependencies": { + "@biomejs/biome": "2.0.5", + "@commitlint/cli": "^19.8.1", + "@commitlint/config-conventional": "^19.8.1", + "@fumadocs/cli": "^0.2.1", + "@tailwindcss/postcss": "^4.1.10", + "@types/hast": "^3.0.4", + "@types/mdx": "^2.0.13", + "@types/node": "24.0.3", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "dotenv-cli": "^8.0.0", + "eslint": "^9.29.0", + "eslint-config-next": "15.3.4", + "gray-matter": "^4.0.3", + "lint-staged": "^16.1.2", + "next-validate-link": "^1.5.2", + "postcss": "^8.5.6", + "prettier": "^3.6.2", + "source-map-support": "^0.5.21", + "tailwindcss": "^4.1.10", + "tinyglobby": "^0.2.14", + "ts-morph": "^26.0.0", + "tsx": "^4.20.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=22" + }, + "pnpm": { + "onlyBuiltDependencies": [ + "@tailwindcss/oxide", + "esbuild", + "sharp", + "unrs-resolver" + ] + } +} diff --git a/docs/parser-info.md b/docs/parser-info.md deleted file mode 100644 index 823b2cc..0000000 --- a/docs/parser-info.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -layout: default -title: Parser Information -parent: API Reference -nav_order: 3 ---- - -# Parser Information - -This guide provides comprehensive information about the LuaTS parsers and their usage. - -## Parser Overview - -LuaTS includes two main parsers: - -1. **Lua Parser** (`parsers/lua.ts`) - - Parses standard Lua syntax - - Supports Lua 5.4 features - - Handles Lua-specific constructs - -2. **Luau Parser** (`parsers/luau.ts`) - - Parses Luau (Roblox) syntax - - Supports Luau type annotations - - Handles Luau-specific features - -## Parser Features - -### Lua Parser - -```typescript -// Lua-specific features - -// Table constructors -{ - key = value, - [key] = value, - value -} - -// Function definitions -function foo() end - -// Local function declarations -local function bar() end - -// Multiple return values -local a, b = func() - -// Vararg -function foo(...) - local args = {...} -end -``` - -### Luau Parser - -```typescript -// Luau-specific features - -// Type annotations -local x: number = 5 - -// Table types -local t: {string} = {} - -// Function types -local f: (number) -> string = function(x) - return tostring(x) -end - -// Union types -local value: string | number = "hello" - -// Intersection types -local user: Base & {name: string} = {} -``` - -## Error Handling - -### Syntax Errors - -```typescript -// Invalid syntax -local x = { -- Missing closing brace - -// Error message: -// Syntax error: expected '}' near end of file -``` - -### Type Errors - -```typescript -// Invalid type annotation -local x: invalid_type = 5 - -// Error message: -// Unknown type 'invalid_type' -``` - -### Recovery - -```typescript -// Parser attempts to recover from errors -local x = { -- Missing closing brace -local y = 5 -- Still processes this line -``` - -## Performance Considerations - -### Memory Usage - -```typescript -// Large files -const MAX_FILE_SIZE = 1024 * 1024; // 1MB - -// Deep recursion -const MAX_DEPTH = 1000; -``` - -### Optimization - -```typescript -// Use batch processing -const BATCH_SIZE = 100; - -// Use streaming for large files -const CHUNK_SIZE = 64 * 1024; // 64KB -``` - -## Best Practices - -### Code Organization - -```typescript -// Separate type definitions -local types = { - Vector2 = { - x: number, - y: number - } -} - -// Separate implementation -local impl = { - createVector2 = function(x: number, y: number): Vector2 - return { x = x, y = y } - end -} -``` - -### Type Safety - -```typescript -// Use type guards -local function isVector2(value: any): boolean - return type(value) == "table" and - type(value.x) == "number" and - type(value.y) == "number" -end - -// Use type assertions -local function getVector2(value: any): Vector2 - assert(isVector2(value)) - return value -end -``` - -### Error Handling - -```typescript -// Handle parse errors -try - local ast = parseLua(code) -catch - error("Failed to parse Lua code") -end - -// Handle type errors -try - local ts = generateTypes(ast) -catch - error("Failed to generate TypeScript") -end -``` - -## Troubleshooting - -### Common Issues - -1. **Syntax Errors** - ```typescript - // Missing semicolons - local x = 5 - local y = 10 -- Error: expected ';' before 'local' - ``` - -2. **Type Errors** - ```typescript - // Invalid type inference - local x = "hello" -- Inferred as string - local y: number = x -- Error: string is not assignable to number - ``` - -3. **Performance Issues** - ```typescript - // Large AST nodes - local t = { - -- 1000+ properties - } -- Error: too many AST nodes - ``` - -## Advanced Usage - -### Custom Parsers - -```typescript -// Create a custom parser -local function parseCustom(code: string) - local ast = parseLua(code) - -- Add custom transformations - return ast -end - -// Use with LuaTS -local ts = generateTypes(parseCustom(code)) -``` - -### Parser Extensions - -```typescript -// Extend the parser -local function extendParser(parser: Parser) - parser:addRule("customType", function() - -- Custom parsing logic - end) - return parser -end - -// Use extended parser -local ts = generateTypes(extendParser(parseLua(code))) -``` - -## Best Practices for Large Projects - -1. **Modularization** - ```typescript - -- Separate type definitions - local types = require("types") - -- Separate implementation - local impl = require("impl") - ``` - -2. **Type Safety** - ```typescript - -- Use strict type checking - local strict = true - -- Use type guards - local function isType(value: any): boolean - return strict and type(value) == "table" - end - ``` - -3. **Error Handling** - ```typescript - -- Use try-catch blocks - try - local ast = parseLua(code) - catch - error("Failed to parse code") - end - ``` - -4. **Performance Optimization** - ```typescript - -- Use batch processing - local BATCH_SIZE = 100 - -- Use streaming - local CHUNK_SIZE = 64 * 1024 - ``` diff --git a/docs/postcss.config.js b/docs/postcss.config.js new file mode 100644 index 0000000..483f378 --- /dev/null +++ b/docs/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; diff --git a/docs/public/banner.png b/docs/public/banner.png new file mode 100644 index 0000000..ecfc410 Binary files /dev/null and b/docs/public/banner.png differ diff --git a/docs/public/logo.svg b/docs/public/logo.svg new file mode 100644 index 0000000..e3820d7 --- /dev/null +++ b/docs/public/logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/docs/public/sidebanner.webp b/docs/public/sidebanner.webp new file mode 100644 index 0000000..ecfc410 Binary files /dev/null and b/docs/public/sidebanner.webp differ diff --git a/docs/source.config.ts b/docs/source.config.ts new file mode 100644 index 0000000..f5575c3 --- /dev/null +++ b/docs/source.config.ts @@ -0,0 +1,88 @@ +import { + rehypeCodeDefaultOptions, + remarkSteps, +} from "fumadocs-core/mdx-plugins"; +import { remarkInstall } from "fumadocs-docgen"; +import { + defineConfig, + defineDocs, + frontmatterSchema, + metaSchema, +} from "fumadocs-mdx/config"; +import { transformerTwoslash } from "fumadocs-twoslash"; +import { createFileSystemTypesCache } from "fumadocs-twoslash/cache-fs"; +import { remarkAutoTypeTable } from "fumadocs-typescript"; +import type { ElementContent } from "hast"; +import rehypeKatex from "rehype-katex"; +import remarkMath from "remark-math"; +import { z } from "zod"; + +export const docs = defineDocs({ + docs: { + async: true, + schema: frontmatterSchema.extend({ + preview: z.string().optional(), + index: z.boolean().default(false), + /** + * API routes only + */ + method: z.string().optional(), + }), + }, + meta: { + schema: metaSchema.extend({ + description: z.string().optional(), + }), + }, +}); + +export default defineConfig({ + lastModifiedTime: "git", + mdxOptions: { + rehypeCodeOptions: { + lazy: true, + experimentalJSEngine: true, + langs: ["ts", "js", "html", "tsx", "mdx", "lua", "luau"], + inline: "tailing-curly-colon", + themes: { + light: "tokyo-night", + dark: "tokyo-night", + }, + transformers: [ + ...(rehypeCodeDefaultOptions.transformers ?? []), + transformerTwoslash({ + typesCache: createFileSystemTypesCache(), + }), + { + name: "@shikijs/transformers:remove-notation-escape", + code(hast) { + function replace(node: ElementContent): void { + if (node.type === "text") { + node.value = node.value.replace("[\\!code", "[!code"); + } else if ("children" in node) { + for (const child of node.children) { + replace(child); + } + } + } + + replace(hast); + return hast; + }, + }, + ], + }, + remarkCodeTabOptions: { + parseMdx: true, + }, + remarkPlugins: [ + remarkSteps, + remarkMath, + remarkAutoTypeTable, + [remarkInstall, { persist: { id: "package-manager" } }], + ], + rehypePlugins: (v) => [rehypeKatex, ...v], + format: "mdx", + development: process.env.NODE_ENV === "development", + }, +}); diff --git a/docs/src/app/(home)/layout.tsx b/docs/src/app/(home)/layout.tsx new file mode 100644 index 0000000..38e328b --- /dev/null +++ b/docs/src/app/(home)/layout.tsx @@ -0,0 +1,7 @@ +import { HomeLayout } from "fumadocs-ui/layouts/home"; +import type { ReactNode } from "react"; +import { baseOptions } from "../layout.config"; + +export default function Layout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/docs/src/app/(home)/page.tsx b/docs/src/app/(home)/page.tsx new file mode 100644 index 0000000..a61be84 --- /dev/null +++ b/docs/src/app/(home)/page.tsx @@ -0,0 +1,5 @@ +import Layout from "@/components/layout/Home"; + +export default function Page() { + return ; +} diff --git a/docs/src/app/api/proxy/route.ts b/docs/src/app/api/proxy/route.ts new file mode 100644 index 0000000..6573eb8 --- /dev/null +++ b/docs/src/app/api/proxy/route.ts @@ -0,0 +1,3 @@ +import { openapi } from "@/lib/source"; + +export const { GET, HEAD, PUT, POST, PATCH, DELETE } = openapi.createProxy(); diff --git a/docs/src/app/api/search/route.ts b/docs/src/app/api/search/route.ts new file mode 100644 index 0000000..9bbc84e --- /dev/null +++ b/docs/src/app/api/search/route.ts @@ -0,0 +1,35 @@ +import { createSearchAPI } from "fumadocs-core/search/server"; +import { source } from "@/lib/source"; + +export const { GET } = createSearchAPI("advanced", { + indexes: await Promise.all( + source.getPages().map(async (page) => { + try { + const data = await page.data.load(); + return { + title: page.data.title, + description: page.data.description, + url: page.url, + id: page.url, + structuredData: { + headings: data.structuredData?.headings || [], + contents: data.structuredData?.contents || [], + }, + }; + } catch (error) { + console.error(`Error loading page ${page.url}:`, error); + // Return a minimal index entry if we can't load the full page + return { + title: page.data.title || "Untitled", + description: page.data.description || "", + url: page.url, + id: page.url, + structuredData: { + headings: [], + contents: [], + }, + }; + } + }), + ), +}); diff --git a/docs/src/app/docs/[[...slug]]/page.tsx b/docs/src/app/docs/[[...slug]]/page.tsx new file mode 100644 index 0000000..e909a80 --- /dev/null +++ b/docs/src/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,181 @@ +import * as path from "node:path"; +import Link from "fumadocs-core/link"; +import { getPageTreePeers } from "fumadocs-core/server"; +import { APIPage } from "fumadocs-openapi/ui"; +import * as Twoslash from "fumadocs-twoslash/ui"; +import { createGenerator } from "fumadocs-typescript"; +import { AutoTypeTable } from "fumadocs-typescript/ui"; +import { Banner } from "fumadocs-ui/components/banner"; +import { Callout } from "fumadocs-ui/components/callout"; +import { Card, Cards } from "fumadocs-ui/components/card"; +import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; +import { TypeTable } from "fumadocs-ui/components/type-table"; +import { + PageArticle, + PageBreadcrumb, + PageFooter, + PageLastUpdate, + PageRoot, + PageTOC, + PageTOCItems, + PageTOCPopover, + PageTOCPopoverContent, + PageTOCPopoverItems, + PageTOCPopoverTrigger, + PageTOCTitle, +} from "fumadocs-ui/layouts/docs/page"; +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import type { ComponentProps, FC, ReactElement } from "react"; +import { Mermaid } from "@/components/mdx/mermaid"; +import { createMetadata, baseUrl } from "@/lib/metadata"; +import { openapi, source } from "@/lib/source"; +import { getMDXComponents } from "@/mdx-components"; +import { Step, Steps } from "fumadocs-ui/components/steps"; +import { InlineTOC } from 'fumadocs-ui/components/inline-toc'; +import { ImageZoom } from 'fumadocs-ui/components/image-zoom'; + +const generator = createGenerator(); + +export const revalidate = false; + +export default async function Page(props: { + params: Promise<{ slug: string[] }>; +}): Promise { + const params = await props.params; + const page = source.getPage(params.slug); + + if (!page) notFound(); + + const { body: Mdx, toc, lastModified } = await page.data.load(); + + return ( + + {toc.length > 0 && ( + + + + + + + )} + + +

{page.data.title}

+

+ {page.data.description} +

+
+ { + const found = source.getPageByHref(href ?? "", { + dir: path.dirname(page.path), + }); + + if (!found) return ; + + return ( +
+ + +

{found.page.data.title}

+

+ {found.page.data.description} +

+
+ ); + }, + Banner, + Mermaid, + TypeTable, + Accordion, + Steps, + InlineTOC, + Step, + Accordions, + AutoTypeTable: (props) => ( + + ), + img: (props) => , + blockquote: Callout as unknown as FC< + ComponentProps<"blockquote"> + >, + APIPage: (props) => ( + + ), + DocsCategory: ({ url }) => , + })} + /> + {page.data.index ? : null} +
+ {lastModified && } + +
+ {toc.length > 0 && ( + + + + + )} +
+ ); +} + +function DocsCategory({ url }: { url: string }) { + return ( + + {getPageTreePeers(source.pageTree, url).map((peer) => ( + + {peer.description} + + ))} + + ); +} + +export async function generateMetadata(props: { + params: Promise<{ slug: string[] }>; +}): Promise { + const { slug = [] } = await props.params; + const page = source.getPage(slug); + if (!page) notFound(); + + const description = + page.data.description; + + const image = { + url: `${baseUrl}/og/${slug.join("/")}/image.png`, + width: 1200, + height: 630, + }; + + return createMetadata({ + title: page.data.title, + description, + openGraph: { + url: `/docs/${page.slugs.join("/")}`, + images: [image], + }, + twitter: { + images: [image], + }, + }); +} + +export function generateStaticParams() { + return source.generateParams(); +} diff --git a/docs/src/app/docs/layout.tsx b/docs/src/app/docs/layout.tsx new file mode 100644 index 0000000..2964e48 --- /dev/null +++ b/docs/src/app/docs/layout.tsx @@ -0,0 +1,58 @@ +import { DocsLayout } from "fumadocs-ui/layouts/docs"; +import Image from "next/image"; +import type { ReactNode } from "react"; +import { baseOptions, linkItems } from "@/app/layout.config"; +import { source } from "@/lib/source"; +import "katex/dist/katex.min.css"; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + item.type === "icon")} + nav={{ + ...baseOptions.nav, + title: ( + <> + Logo + + ), + }} + sidebar={{ + tabs: { + transform(option, node) { + const meta = source.getNodeMeta(node); + if (!meta || !node.icon) return option; + + const color = `var(--${meta.path.split("/")[0]}-color, var(--color-fd-foreground))`; + + return { + ...option, + icon: ( +
+ {node.icon} +
+ ), + }; + }, + }, + }} + > + {children} +
+ ); +} diff --git a/docs/src/app/icon.png b/docs/src/app/icon.png new file mode 100644 index 0000000..faee907 Binary files /dev/null and b/docs/src/app/icon.png differ diff --git a/docs/src/app/layout.config.tsx b/docs/src/app/layout.config.tsx new file mode 100644 index 0000000..53553c8 --- /dev/null +++ b/docs/src/app/layout.config.tsx @@ -0,0 +1,79 @@ +import { GithubInfo } from "fumadocs-ui/components/github-info"; +import type { LinkItemType } from "fumadocs-ui/layouts/docs"; +import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; +import Image from "next/image"; +import { FaBook, FaCogs, FaDiscord, FaDownload } from "react-icons/fa"; +import { SiGithub } from "react-icons/si"; + +/** + * Shared layout configurations + * + * you can configure layouts individually from: + * Home Layout: app/(home)/layout.tsx + * Docs Layout: app/docs/layout.tsx + */ + +export const linkItems: LinkItemType[] = [ + { + type: "icon", + url: "https://discord.gg/3z65bpPWhC", + text: "Support", + icon: , + external: true, + }, + { + type: "icon", + url: "https://github.com/CodeMeAPixel", + text: "Github", + icon: , + external: true, + }, +]; + +export const baseOptions: BaseLayoutProps = { + nav: { + title: ( + <> +
+ Logo +

LuaTS

+
+ + ), + transparentMode: "top", + }, + links: [ + { + type: "menu", + text: "Docs", + items: [ + { + icon: , + text: "User Guide", + description: "How to guide on setting up LuaTS", + url: "/docs/user", + }, + { + icon: , + text: "API Refrence", + description: + "API level knowledge for using LuaTS", + url: "/docs/api-refrence", + }, + { + icon: , + text: "Plugins", + description: + "LuaTS provides a comprehensive plugin system that allows you to customize and extend the type generation process.", + url: "/docs/plugins", + }, + ], + }, + ...linkItems, + ], +}; diff --git a/docs/src/app/layout.tsx b/docs/src/app/layout.tsx new file mode 100644 index 0000000..d46ad14 --- /dev/null +++ b/docs/src/app/layout.tsx @@ -0,0 +1,55 @@ +import "@/styles/globals.css"; +import { RootProvider } from "fumadocs-ui/provider"; +import type { Viewport } from "next"; +import { Inter } from "next/font/google"; +import type { ReactNode } from "react"; +import "katex/dist/katex.css"; +import type { Metadata } from "next"; + +const inter = Inter({ + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: { + template: "%s | LuaTS", + default: "A TypeScript library for parsing, formatting, and providing type interfaces for Lua and Luau code.", + }, + icons: { + icon: "https://luats.lol/logo.svg", + shortcut: "https://luats.lol/logo.svg", + apple: "https://luats.lol/logo.svg", + }, + openGraph: { + title: "LuaTS - A TypeScript library for parsing, formatting, and providing type interfaces for Lua and Luau code.", + url: "https://luats.lol", + siteName: "LuaTS | Docs", + images: { + url: "https://luats.lol/banner.png", + width: 1200, + height: 630, + alt: "LuaTS - A TypeScript library for parsing, formatting, and providing type interfaces for Lua and Luau code.", + }, + }, +}; + +export const viewport: Viewport = { + themeColor: [ + { media: "(prefers-color-scheme: dark)", color: "#0A0A0A" }, + { media: "(prefers-color-scheme: light)", color: "#fff" }, + ], +}; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + + {children} + + + ); +} diff --git a/docs/src/app/og/[...slug]/fonts/Inter-Bold.ttf b/docs/src/app/og/[...slug]/fonts/Inter-Bold.ttf new file mode 100644 index 0000000..46b3583 Binary files /dev/null and b/docs/src/app/og/[...slug]/fonts/Inter-Bold.ttf differ diff --git a/docs/src/app/og/[...slug]/fonts/Inter-Regular.ttf b/docs/src/app/og/[...slug]/fonts/Inter-Regular.ttf new file mode 100644 index 0000000..6b088a7 Binary files /dev/null and b/docs/src/app/og/[...slug]/fonts/Inter-Regular.ttf differ diff --git a/docs/src/app/og/[...slug]/fonts/Inter-SemiBold.ttf b/docs/src/app/og/[...slug]/fonts/Inter-SemiBold.ttf new file mode 100644 index 0000000..ceb8576 Binary files /dev/null and b/docs/src/app/og/[...slug]/fonts/Inter-SemiBold.ttf differ diff --git a/docs/src/app/og/[...slug]/og.tsx b/docs/src/app/og/[...slug]/og.tsx new file mode 100644 index 0000000..584e1c8 --- /dev/null +++ b/docs/src/app/og/[...slug]/og.tsx @@ -0,0 +1,116 @@ +import type { ImageResponseOptions } from "next/dist/compiled/@vercel/og/types"; +import { ImageResponse } from "next/og"; +import type { ReactElement, ReactNode } from "react"; + +const title = "LuaTS"; + +interface GenerateProps { + title: ReactNode; + tag: string; + description?: ReactNode; + primaryTextColor?: string; +} + +export function generateOGImage( + options: GenerateProps & ImageResponseOptions, +): ImageResponse { + const { title, tag, description, primaryTextColor, ...rest } = options; + + return new ImageResponse( + generate({ + title, + tag, + description, + primaryTextColor, + }), + { + width: 1200, + height: 630, + ...rest, + }, + ); +} + +export function generate({ + primaryTextColor = "rgb(255,150,255)", + ...props +}: GenerateProps): ReactElement { + return ( +
+
+
+ LuaTS Logo +

+ {title} +

+
+

+ {props.tag.replace(/-/g, " ")} +

+

+ {props.title} +

+

+ {props.description} +

+
+
+ ); +} diff --git a/docs/src/app/og/[...slug]/route.tsx b/docs/src/app/og/[...slug]/route.tsx new file mode 100644 index 0000000..6e952b7 --- /dev/null +++ b/docs/src/app/og/[...slug]/route.tsx @@ -0,0 +1,52 @@ +import { readFileSync } from "node:fs"; +import { notFound } from "next/navigation"; +import { generateOGImage } from "@/app/og/[...slug]/og"; +import { source } from "@/lib/source"; + +const font = readFileSync("./src/app/og/[...slug]/fonts/Inter-Regular.ttf"); +const fontSemiBold = readFileSync( + "./src/app/og/[...slug]/fonts/Inter-SemiBold.ttf", +); +const fontBold = readFileSync("./src/app/og/[...slug]/fonts/Inter-Bold.ttf"); + +export async function GET( + _req: Request, + { params }: { params: Promise<{ slug: string[] }> }, +) { + const { slug } = await params; + const page = source.getPage(slug.slice(0, -1)); + if (!page) notFound(); + + return generateOGImage({ + primaryTextColor: "rgb(240,240,240)", + title: page.data.title, + description: page.data.description, + tag: page.slugs[0], + fonts: [ + { + name: "Inter", + data: font, + weight: 400, + }, + { + name: "Inter", + data: fontSemiBold, + weight: 600, + }, + { + name: "Inter", + data: fontBold, + weight: 700, + }, + ], + }); +} + +export function generateStaticParams(): { + slug: string[]; +}[] { + return source.generateParams().map((page) => ({ + ...page, + slug: [...page.slug, "image.png"], + })); +} diff --git a/docs/src/app/sitemap.ts b/docs/src/app/sitemap.ts new file mode 100644 index 0000000..e5756d0 --- /dev/null +++ b/docs/src/app/sitemap.ts @@ -0,0 +1,33 @@ +import type { MetadataRoute } from "next"; +import { baseUrl } from "@/lib/metadata"; +import { source } from "@/lib/source"; + +export const revalidate = false; + +export default async function sitemap(): Promise { + const url = (path: string): string => new URL(path, baseUrl).toString(); + + return [ + { + url: url("/"), + changeFrequency: "monthly", + priority: 1, + }, + { + url: url("/docs"), + changeFrequency: "monthly", + priority: 0.8, + }, + ...(await Promise.all( + source.getPages().map(async (page) => { + const { lastModified } = await page.data.load(); + return { + url: url(page.url), + lastModified: lastModified ? new Date(lastModified) : undefined, + changeFrequency: "weekly", + priority: 0.5, + } as MetadataRoute.Sitemap[number]; + }), + )), + ]; +} diff --git a/docs/src/components/layout/Home/code.tsx b/docs/src/components/layout/Home/code.tsx new file mode 100644 index 0000000..55c534a --- /dev/null +++ b/docs/src/components/layout/Home/code.tsx @@ -0,0 +1,187 @@ +"use client"; + +import React from 'react'; +import { + MousePointerClick, + PanelTopDashed, + SquareMenu, + SquareSlash, + ExternalLink +} from 'lucide-react'; +import { CodeBlock } from '../global/codeblock'; + +interface CardProps { + title: string; + description: string; + href: string; + icon: React.ReactNode; + children: React.ReactNode; +} + +const Card: React.FC = ({ title, description, href, icon, children }) => { + return ( +
+
+
+
+ {icon} +
+
+
+

{title}

+ +
+

{description}

+
+
+
+ {children} +
+
+
+ ); +}; + +const Separator: React.FC = () => { + return
; +}; + +interface SectionTitleProps { + content: React.ReactNode; +} + +const SectionTitle: React.FC = ({ content }) => { + return ( +
+
+

+ {content} +

+
+ ); +}; + +const QuickExample = `import { generateTypes } from 'luats'; + +const tsCode = generateTypes(\` + type Vector3 = { + x: number, + y: number, + z: number + } +\`); + +console.log(tsCode); +// Output: +// interface Vector3 { +// x: number; +// y: number; +// z: number; +// }`; + +const basicUsage = `import { parseLuau } from 'luats'; +// or import the class directly +import { LuauParser } from 'luats/parsers/luau'; + +// Parse Luau code with type annotations +const ast = parseLuau(\` + type Person = { + name: string, + age: number, + active?: boolean + } + + local function createPerson(name: string, age: number): Person + return { + name = name, + age = age, + active = true + } + end +\`); + +console.log(ast);`; + +const FormattingLuaCode = `import { formatLua } from 'luats'; +import { LuaFormatter } from 'luats/clients/formatter'; + +// Using convenience function +const messyCode = "local x=1+2 local y=x*3 if x>5 then print(\\"big\\") end"; +const formatted = formatLua(messyCode); + +// Using class with custom options +const formatter = new LuaFormatter({ + indentSize: 4, + insertSpaceAroundOperators: true, + insertSpaceAfterComma: true, + maxLineLength: 100 +}); + +const customFormatted = formatter.format(messyCode);`; + +const lexerCode = `import { Lexer, TokenType } from 'luats/clients/lexer'; + +const lexer = new Lexer(\` + local name: string = "World" + print("Hello, " .. name) +\`); + +const tokens = lexer.tokenize(); + +tokens.forEach(token => { + console.log(\`\${token.type}: "\${token.value}" at \${token.line}:\${token.column}\`); +});`; + +export default function HomeBuilders() { + return ( +
+ + +
+ } + > + + + + } + > + + +
+ + + + + +
+ } + > + + + + } + > + + +
+ + +
+ ); +} \ No newline at end of file diff --git a/docs/src/components/layout/Home/index.tsx b/docs/src/components/layout/Home/index.tsx new file mode 100644 index 0000000..e1ad4d7 --- /dev/null +++ b/docs/src/components/layout/Home/index.tsx @@ -0,0 +1,260 @@ +"use client" + +import { Card, Cards } from "fumadocs-ui/components/card"; +import { motion } from "framer-motion" +import { FaGithub, FaCode, FaExchangeAlt, FaChevronLeft, FaCheckCircle, FaTools, FaBook, FaPuzzlePiece } from "react-icons/fa" +import { SiTypescript, SiLua } from "react-icons/si" +import Link from "next/link" +import HomeBuilders from "./code" +import { Install } from "./install" + +function Button({ + children, + variant = "default", + ...props +}: React.ButtonHTMLAttributes & { + variant?: "default" | "outline" +}) { + const base = "inline-flex items-center justify-center px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2" + const variants = { + default: "bg-primary text-white hover:bg-primary/90 focus:ring-primary", + outline: "border border-border text-foreground hover:bg-muted focus:ring-ring" + } + return ( + + ) +} + +function CardHeader({ children, className = "" }: { children: React.ReactNode; className?: string }) { + return
{children}
+} + +function CardTitle({ children, className = "" }: { children: React.ReactNode; className?: string }) { + return

{children}

+} + +function CardContent({ children }: { children: React.ReactNode }) { + return
{children}
+} + +export default function Component() { + const fadeIn = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0, transition: { duration: 0.6 } }, + } + + const staggerContainer = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.1, + }, + }, + } + + const featureList = [ + { + icon: FaExchangeAlt, + title: "Type Conversion", + description: "Converts Lua/Luau type declarations into TypeScript interfaces seamlessly.", + }, + { + icon: SiTypescript, + title: "TypeScript Mapping", + description: "Maps Lua types to TypeScript equivalents (string, number, boolean, etc.).", + }, + { + icon: FaCheckCircle, + title: "Optional Types", + description: "Supports optional types (e.g., `foo: string?` becomes `foo?: string`).", + }, + { + icon: FaCode, + title: "Table & Function Types", + description: + "Handles complex table types (`{string}` → `string[]`) and converts Luau function types to TS arrow functions.", + }, + { + icon: FaBook, + title: "JSDoc Preservation", + description: "Preserves comments and maps them directly to JSDoc format in TypeScript.", + }, + { + icon: FaTools, + title: "CLI Tooling", + description: "Includes a robust CLI tool for single-file or batch directory conversion with various options.", + }, + { + icon: FaPuzzlePiece, + title: "Plugin System", + description: "Extend type generation with a powerful plugin hook system for custom transforms.", + }, + { + icon: FaCode, + title: "Programmatic API", + description: "Offers a comprehensive programmatic API for integration into your build workflows.", + }, + ] + + return ( +
+
+ {/* Hero Section */} +
+
+
+ +
+

+ LuaTS: Seamless Lua/Luau to{" "} + TypeScript Type Conversion +

+

+ A powerful library for parsing, formatting, and providing robust TypeScript interfaces for your Lua + and Luau codebases. +

+
+
+ + + Get Started + + + + View on GitHub + + + +
+
+ + + + +
+
+
+ +
+
+ + + +
+
+ + {/* Features Section */} +
+
+ +
+

Key Features

+

+ LuaTS provides a comprehensive set of tools to bridge your Lua/Luau code with TypeScript. +

+
+
+ + {featureList.map((feature, index) => ( + + + +
+ +
+ {feature.title} +
+ +

{feature.description}

+
+
+
+ ))} +
+
+
+ + {/* Contribution Section */} +
+
+ +

Contribute to LuaTS

+

+ LuaTS is an open-source project and welcomes contributions from the community. Whether it's bug fixes, + new features, or documentation improvements, your help is valuable! +

+ + + Contribution Guide + +
+
+
+
+ + {/* Footer */} +
+

© {"2024-2025 CodeMeAPixel. All rights reserved."}

+ +
+
+ ) +} diff --git a/docs/src/components/layout/Home/install.tsx b/docs/src/components/layout/Home/install.tsx new file mode 100644 index 0000000..967120c --- /dev/null +++ b/docs/src/components/layout/Home/install.tsx @@ -0,0 +1,85 @@ +'use client'; + +import { + CheckIcon, + CopyIcon, + TerminalIcon, +} from 'lucide-react'; +import { useEffect, useState } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; + +import { cn } from '@/lib/cn'; + +const contents = ['npm install luats', 'bun add luats', 'yarn install luats']; + +export function Install( + props: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLButtonElement + >, +) { + const [copied, setCopied] = useState(false); + const [index, setIndex] = useState(0); + + const content = contents[index]; + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(content); + setCopied(true); + setTimeout(() => setCopied(false), 3000); + } catch (error) { + setCopied(false); + console.error(error); + } + }; + + useEffect(() => { + const interval = setInterval(() => { + setIndex((prev) => (prev + 1) % contents.length); + }, 2500); + return () => clearInterval(interval); + }, []); + + return ( +
+ +
+ ); +} diff --git a/docs/src/components/layout/global/codeblock.tsx b/docs/src/components/layout/global/codeblock.tsx new file mode 100644 index 0000000..82b18ff --- /dev/null +++ b/docs/src/components/layout/global/codeblock.tsx @@ -0,0 +1,124 @@ +'use client'; + +import { cn } from '@/lib/cn'; +import * as Base from 'fumadocs-ui/components/codeblock'; +import { Fragment, type HTMLAttributes, useEffect, useState } from 'react'; +import { jsx, jsxs } from 'react/jsx-runtime'; + +export type CodeBlockProps = HTMLAttributes & { + code: string; + wrapper?: Base.CodeBlockProps; + lang: string; +}; + +export function CodeBlock({ + code, + lang, + wrapper, + ...props +}: CodeBlockProps) { + const [renderedCode, setRenderedCode] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + async function renderCode() { + try { + // Dynamic import to avoid SSR issues + const { codeToHast } = await import('shiki'); + const { toJsxRuntime } = await import('hast-util-to-jsx-runtime'); + + const hast = await codeToHast(code, { + lang, + defaultColor: false, + themes: { + light: 'min-light', + dark: 'github-dark-default', + }, + }); + + const rendered = toJsxRuntime(hast, { + jsx: jsx as any, + jsxs: jsxs as any, + Fragment, + development: false, + components: { + pre: Base.Pre, + }, + }); + + setRenderedCode(rendered); + } catch (error) { + console.error('Error rendering code:', error); + // Fallback to plain text + setRenderedCode( + + {code} + + ); + } finally { + setIsLoading(false); + } + } + + renderCode(); + }, [code, lang]); + + if (isLoading) { + return ( + + + Loading... + + + ); + } + + return ( + + {renderedCode} + + ); +} + +interface PrettyCodeBlockOptions extends CodeBlockProps { + background: React.ReactNode; + container?: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDivElement + >; +} + +export function PrettyCodeBlock({ + background, + container, + ...props +}: PrettyCodeBlockOptions) { + return ( +
div>canvas]:hidden [&>div>canvas]:sm:block', + container?.className, + )} + > + {background} + +
+ ); +} \ No newline at end of file diff --git a/docs/src/components/layout/global/icon.tsx b/docs/src/components/layout/global/icon.tsx new file mode 100644 index 0000000..0e70feb --- /dev/null +++ b/docs/src/components/layout/global/icon.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { IconType } from "react-icons"; + +interface IconContainerProps { + icon: IconType; +} + +export const IconContainer: React.FC = ({ icon: Icon }) => { + return ( +
+ +
+ ); +}; diff --git a/docs/src/components/mdx/mermaid.tsx b/docs/src/components/mdx/mermaid.tsx new file mode 100644 index 0000000..0f12665 --- /dev/null +++ b/docs/src/components/mdx/mermaid.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { useTheme } from "next-themes"; +import { useEffect, useId, useRef, useState } from "react"; + +export function Mermaid({ chart }: { chart: string }) { + const id = useId(); + const [svg, setSvg] = useState(""); + const containerRef = useRef(null); + const currentChartRef = useRef(null); + const { resolvedTheme } = useTheme(); + + useEffect(() => { + if (currentChartRef.current === chart || !containerRef.current) return; + const container = containerRef.current; + currentChartRef.current = chart; + + async function renderChart() { + const { default: mermaid } = await import("mermaid"); + + try { + // configure mermaid + mermaid.initialize({ + startOnLoad: false, + securityLevel: "loose", + fontFamily: "inherit", + themeCSS: "margin: 1.5rem auto 0;", + theme: resolvedTheme === "dark" ? "dark" : "default", + }); + + const { svg, bindFunctions } = await mermaid.render( + id, + chart.replaceAll("\\n", "\n"), + ); + + bindFunctions?.(container); + setSvg(svg); + } catch (error) { + console.error("Error while rendering mermaid", error); + } + } + + void renderChart(); + }, [chart, id, resolvedTheme]); + + return
; +} diff --git a/docs/src/lib/cn.ts b/docs/src/lib/cn.ts new file mode 100644 index 0000000..365058c --- /dev/null +++ b/docs/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/docs/src/lib/fumadocs/cn.ts b/docs/src/lib/fumadocs/cn.ts new file mode 100644 index 0000000..8e473da --- /dev/null +++ b/docs/src/lib/fumadocs/cn.ts @@ -0,0 +1 @@ +export { twMerge as cn } from "tailwind-merge"; diff --git a/docs/src/lib/metadata-image.ts b/docs/src/lib/metadata-image.ts new file mode 100644 index 0000000..480496c --- /dev/null +++ b/docs/src/lib/metadata-image.ts @@ -0,0 +1,7 @@ +import { createMetadataImage } from "fumadocs-core/server"; +import { source } from "@/lib/source"; + +export const metadataImage = createMetadataImage({ + source, + imageRoute: "og", +}); diff --git a/docs/src/lib/metadata.ts b/docs/src/lib/metadata.ts new file mode 100644 index 0000000..eb6cb0c --- /dev/null +++ b/docs/src/lib/metadata.ts @@ -0,0 +1,52 @@ +import type { Metadata } from "next/types"; + +export const baseUrl = "https://luats.lol"; +const title = "LuaTS | Docs"; + +export function createMetadata(override: Metadata): Metadata { + // Handle the override images + const images = override.openGraph?.images; + const defaultImage = "/banner.png"; + + let imageUrl = defaultImage; + if (images) { + if (typeof images === "string") { + imageUrl = images; + } else if (Array.isArray(images) && images.length > 0) { + imageUrl = typeof images[0] === "string" ? images[0] : defaultImage; + } + } + + // Ensure absolute URL + const absoluteImageUrl = imageUrl.startsWith("http") + ? imageUrl + : `${baseUrl}${imageUrl}`; + + return { + ...override, + openGraph: { + title: override.title ?? undefined, + description: override.description ?? undefined, + url: baseUrl, + images: { + url: absoluteImageUrl, + width: 1200, + height: 630, + }, + siteName: title, + ...override.openGraph, + }, + twitter: { + card: "summary_large_image", + creator: "@ranveersoni98", + title: override.title ?? undefined, + description: override.description ?? undefined, + images: { + url: absoluteImageUrl, + width: 1200, + height: 630, + }, + ...override.twitter, + }, + }; +} diff --git a/docs/src/lib/source.ts b/docs/src/lib/source.ts new file mode 100644 index 0000000..6f933e9 --- /dev/null +++ b/docs/src/lib/source.ts @@ -0,0 +1,72 @@ +import type { InferMetaType, InferPageType } from "fumadocs-core/source"; +import { loader } from "fumadocs-core/source"; +import { attachFile, createOpenAPI } from "fumadocs-openapi/server"; +import { icons as LucideIcons } from "lucide-react"; +import { createElement } from "react"; +import { docs } from "../../.source"; +import { IconType } from "react-icons"; +import * as FaIcons from "react-icons/fa"; +import * as MdIcons from "react-icons/md"; +import * as Fa6Icons from "react-icons/fa6"; +import * as TbIcons from "react-icons/tb"; +import * as IoIcons from "react-icons/io5"; +import { IconContainer } from "@/components/layout/global/icon"; + +export const source = loader({ + baseUrl: "/docs", + icon(icon) { + if (icon && icon in MdIcons) { + const IconComponent = MdIcons[icon as keyof typeof MdIcons] as IconType; + return createElement(IconContainer, { + icon: IconComponent, + }); + } + if (icon && icon in FaIcons) { + const IconComponent = FaIcons[icon as keyof typeof FaIcons] as IconType; + return createElement(IconContainer, { + icon: IconComponent, + }); + } + if (icon && icon in Fa6Icons) { + const IconComponent = Fa6Icons[icon as keyof typeof Fa6Icons] as IconType; + return createElement(IconContainer, { + icon: IconComponent, + }); + } + if (icon && icon in IoIcons) { + const IconComponent = IoIcons[icon as keyof typeof IoIcons] as IconType; + return createElement(IconContainer, { + icon: IconComponent, + }); + } + if (icon && icon in TbIcons) { + const IconComponent = TbIcons[icon as keyof typeof TbIcons] as IconType; + return createElement(IconContainer, { + icon: IconComponent, + }); + } + if (icon && icon in LucideIcons) { + const IconComponent = LucideIcons[icon as keyof typeof LucideIcons]; + return createElement(IconContainer, { + icon: IconComponent, + }); + } + }, + source: docs.toFumadocsSource(), + pageTree: { + attachFile, + }, +}); + +export const openapi = createOpenAPI({ + proxyUrl: "/api/proxy", + shikiOptions: { + themes: { + light: "tokyo-night", + dark: "tokyo-night", + }, + }, +}); + +export type Page = InferPageType; +export type Meta = InferMetaType; diff --git a/docs/src/mdx-components.tsx b/docs/src/mdx-components.tsx new file mode 100644 index 0000000..76cc113 --- /dev/null +++ b/docs/src/mdx-components.tsx @@ -0,0 +1,52 @@ +import * as Twoslash from "fumadocs-twoslash/ui"; +import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; +import { Callout } from "fumadocs-ui/components/callout"; +import { File, Files, Folder } from "fumadocs-ui/components/files"; +import { + Tab, + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "fumadocs-ui/components/tabs"; +import { TypeTable } from "fumadocs-ui/components/type-table"; +import defaultMdxComponents from "fumadocs-ui/mdx"; +import * as lucideIcons from "lucide-react"; +import * as FaIcons from "react-icons/fa"; +import * as Fa6Icons from "react-icons/fa6"; +import * as MdIcons from "react-icons/md"; +import * as TbIcons from "react-icons/tb"; +import * as IoIcons from "react-icons/io5"; +import type { MDXComponents } from "mdx/types"; +import { Mermaid } from "@/components/mdx/mermaid"; +import { ImageZoom } from "fumadocs-ui/components/image-zoom"; +import { InlineTOC } from 'fumadocs-ui/components/inline-toc'; + +export function getMDXComponents(components?: MDXComponents): MDXComponents { + return { + ...(lucideIcons as unknown as MDXComponents), + ...(FaIcons as unknown as MDXComponents), + ...(Fa6Icons as unknown as MDXComponents), + ...(MdIcons as unknown as MDXComponents), + ...(TbIcons as unknown as MDXComponents), + ...(IoIcons as unknown as MDXComponents), + ...defaultMdxComponents, + img: (props) => , + ...Twoslash, + File, + Files, + Folder, + Tabs, + TabsContent, + TabsList, + TabsTrigger, + Tab, + Accordion, + InlineTOC, + Accordions, + Mermaid, + TypeTable, + Callout, + ...components, + }; +} diff --git a/docs/src/styles/globals.css b/docs/src/styles/globals.css new file mode 100644 index 0000000..068732e --- /dev/null +++ b/docs/src/styles/globals.css @@ -0,0 +1,4 @@ +@import "tailwindcss"; +@import "fumadocs-ui/css/ocean.css"; +@import "fumadocs-ui/css/preset.css"; +@import "fumadocs-openapi/css/preset.css"; diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 0000000..02f2bb2 --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/*": ["./src/*"], + "@/.source": ["./.source/index.ts"] + }, + "plugins": [ + { + "name": "next" + } + ], + "ignoreDeprecations": "5.0" + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.mts", + "**/*.tsx", + ".next/types/**/*.ts", + "next.config.js", + "tailwind.config.js" + ], + "exclude": ["node_modules"] +}