Initial commit
This commit is contained in:
777
docs/dial/cli-details.md
Normal file
777
docs/dial/cli-details.md
Normal file
@@ -0,0 +1,777 @@
|
||||
1. [Home](/)
|
||||
1. [Dial](/dial)
|
||||
1. Cli Details
|
||||
|
||||
# Dial CLI Reference
|
||||
|
||||
|
||||
The `dial-cli` tool is a powerful command-line utility for generating UI schemas from TypeScript interfaces with Dial annotations. This page provides a complete reference for all CLI features and options.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
The dial-cli is now available as a standalone package for cleaner installation:
|
||||
|
||||
|
||||
```bash
|
||||
# Install globally (recommended for CLI tools)
|
||||
npm install -g @vuer-ai/dial-cli
|
||||
# or
|
||||
pnpm install -g @vuer-ai/dial-cli
|
||||
|
||||
# Or install as a dev dependency
|
||||
npm install --save-dev @vuer-ai/dial-cli
|
||||
# or
|
||||
pnpm add -D @vuer-ai/dial-cli
|
||||
|
||||
```
|
||||
|
||||
|
||||
Once installed, the CLI is available directly:
|
||||
|
||||
|
||||
```bash
|
||||
# If installed globally
|
||||
dial-cli --help
|
||||
|
||||
# If installed as dev dependency
|
||||
npx dial-cli --help
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Benefits of Standalone Package
|
||||
|
||||
|
||||
|
||||
- **Minimal dependencies** - Only includes what's needed for CLI operation (typescript, react-docgen-typescript)
|
||||
|
||||
- **No peer dependency warnings** - Doesn't require React, Tailwind, or other UI dependencies
|
||||
|
||||
- **Smaller install size** - ~32KB unpacked vs entire UI kit
|
||||
|
||||
- **Independent versioning** - CLI updates don't require UI kit updates
|
||||
|
||||
|
||||
|
||||
## Command Line Options
|
||||
|
||||
|
||||
### Basic Usage
|
||||
|
||||
|
||||
```bash
|
||||
dial-cli [options] <files...>
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Options Reference
|
||||
|
||||
|
||||
| Option | Alias | Description | Default |
|
||||
| `--output <dir>` | `-o` | Output directory for generated files | `./metadata` |
|
||||
| `--verbose` | | Enable verbose output with detailed information | `false` |
|
||||
| `--quiet` | | Suppress all output except errors | `false` |
|
||||
| `--remove` | | Remove generated metadata files | `false` |
|
||||
| `--ignore <props>` | `-i` | Comma-separated list of properties to ignore | - |
|
||||
| `--help` | `-h` | Display help information | - |
|
||||
| `--version` | `-v` | Display version information | - |
|
||||
|
||||
|
||||
|
||||
### Verbose Mode
|
||||
|
||||
|
||||
The `--verbose` flag enables detailed output and generates additional files:
|
||||
|
||||
|
||||
```bash
|
||||
dial-cli --verbose MyComponent.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
In verbose mode, dial-cli generates:
|
||||
|
||||
|
||||
|
||||
- `schema.dial` - Combined dial schema for all components (main output)
|
||||
|
||||
- `debug/` - Debug directory containing:
|
||||
|
||||
- `component-raw.json` - Raw docgen output
|
||||
|
||||
- `component-combined.json` - Enhanced metadata
|
||||
|
||||
- `component-schemas.json` - Component schemas
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**Note:** Debug files are organized in a `debug/` subdirectory to keep the main output clean. These files are only generated in verbose mode and are useful for debugging schema generation issues.
|
||||
|
||||
|
||||
### Quiet Mode
|
||||
|
||||
|
||||
The `--quiet` flag suppresses all output except errors, useful for CI/CD:
|
||||
|
||||
|
||||
```bash
|
||||
dial-cli --quiet src/components/*.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Remove Mode
|
||||
|
||||
|
||||
The `--remove` flag cleans up generated metadata files:
|
||||
|
||||
|
||||
```bash
|
||||
# Remove metadata for specific component
|
||||
dial-cli --remove MyComponent.tsx
|
||||
|
||||
# Remove all metadata in output directory
|
||||
dial-cli --remove --output ./metadata
|
||||
|
||||
```
|
||||
|
||||
|
||||
**Important:** The remove command cleans up both the main `schema.dial` file and any debug files in the `debug/` directory. It supports both the current debug directory structure and legacy file locations for backward compatibility.
|
||||
|
||||
|
||||
### Ignore Properties
|
||||
|
||||
|
||||
Exclude specific properties from schema generation:
|
||||
|
||||
|
||||
```bash
|
||||
# Ignore single property
|
||||
dial-cli --ignore ref MyComponent.tsx
|
||||
|
||||
# Ignore multiple properties
|
||||
dial-cli --ignore "ref,key,children" MyComponent.tsx
|
||||
|
||||
# Using short alias
|
||||
dial-cli -i "internalProp,debugValue" Component.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Output Files
|
||||
|
||||
|
||||
### Standard Output (Default)
|
||||
|
||||
|
||||
Without verbose mode, only generates:
|
||||
|
||||
|
||||
|
||||
- `schema.dial` - Combined schema for all processed components
|
||||
|
||||
|
||||
|
||||
### Verbose Output
|
||||
|
||||
|
||||
With `--verbose` flag, generates additional files per component:
|
||||
|
||||
|
||||
|
||||
- `[component]-schemas.json` - Component-specific schema
|
||||
|
||||
- `[component]-raw.json` - Raw react-docgen output
|
||||
|
||||
- `[component]-combined.json` - Enhanced metadata with dial annotations
|
||||
|
||||
- `schema.dial` - Combined schema (always generated)
|
||||
|
||||
|
||||
|
||||
## Group-Level Configuration
|
||||
|
||||
|
||||
You can apply configuration to entire groups of properties using interface-level JSDoc comments:
|
||||
|
||||
|
||||
### Using @dial-no-wrap
|
||||
|
||||
|
||||
The `@dial-no-wrap` annotation prevents line wrapping for all properties in a group:
|
||||
|
||||
|
||||
```tsx
|
||||
interface ComponentProps {
|
||||
/**
|
||||
* Layout configuration for transform properties
|
||||
* @dial transform @dial-no-wrap
|
||||
*/
|
||||
|
||||
/** @dial transform @dial-dtype vector3 */
|
||||
position: number[];
|
||||
|
||||
/** @dial transform @dial-dtype euler */
|
||||
rotation: number[];
|
||||
|
||||
/** @dial transform @dial-dtype vector3 */
|
||||
scale: number[];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
In this example, all properties in the "transform" group (position, rotation, scale) will be displayed on a single line without wrapping.
|
||||
|
||||
|
||||
### Groups in Output Schema
|
||||
|
||||
|
||||
The CLI now generates a `groups` section in the output schema:
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"component": "ExampleBox",
|
||||
"schema": [...],
|
||||
"groups": [
|
||||
{
|
||||
"name": "transform",
|
||||
"noWrap": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
This allows the UI to apply group-specific styling and layout configuration.
|
||||
|
||||
|
||||
## Excluding Properties
|
||||
|
||||
|
||||
There are two ways to exclude properties from dial schema generation:
|
||||
|
||||
|
||||
### 1. Using @dial-ignore Annotation
|
||||
|
||||
|
||||
Add `@dial-ignore` to any property's JSDoc comment to exclude it from the generated schema:
|
||||
|
||||
|
||||
```tsx
|
||||
interface ComponentProps {
|
||||
/**
|
||||
* Public property - included in schema
|
||||
* @dial transform
|
||||
* @dial-dtype vector3
|
||||
*/
|
||||
position: number[];
|
||||
|
||||
/**
|
||||
* Internal state - excluded from schema
|
||||
* @dial-ignore
|
||||
*/
|
||||
_internalCache?: any;
|
||||
|
||||
/**
|
||||
* React ref - excluded from schema
|
||||
* @dial-ignore
|
||||
*/
|
||||
ref?: React.Ref<HTMLDivElement>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 2. Using CLI --ignore Option
|
||||
|
||||
|
||||
The `-i` or `--ignore` option allows you to exclude properties by name or pattern at runtime:
|
||||
|
||||
|
||||
```bash
|
||||
# Exclude specific properties
|
||||
dial-cli -i className -i style Component.tsx
|
||||
|
||||
# Exclude using comma-separated list
|
||||
dial-cli --ignore ref,key,id Component.tsx
|
||||
|
||||
# Exclude using glob patterns
|
||||
dial-cli -i "*Style" -i "on*" -i "_*" Component.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
#### Glob Pattern Examples
|
||||
|
||||
|
||||
| Pattern | Matches | Example Properties |
|
||||
| `*Style` | Ends with "Style" | `containerStyle`, `buttonStyle`, `textStyle` |
|
||||
| `on*` | Starts with "on" | `onClick`, `onChange`, `onSubmit` |
|
||||
| `_*` | Starts with underscore | `_internal`, `_cache`, `_private` |
|
||||
| `*Ref` | Ends with "Ref" | `inputRef`, `containerRef`, `buttonRef` |
|
||||
| `data*` | Starts with "data" | `dataSource`, `dataProvider`, `dataKey` |
|
||||
|
||||
|
||||
|
||||
## Class/Interface Level Suppression
|
||||
|
||||
|
||||
The `@dial-ignore` annotation can be used at the class or interface level to completely suppress dial schema generation for an entire component and all its properties:
|
||||
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* Internal configuration component
|
||||
* @dial-ignore
|
||||
*/
|
||||
interface InternalSettingsProps {
|
||||
apiKey: string;
|
||||
debugMode: boolean;
|
||||
serverUrl: string;
|
||||
// All properties will be excluded from dial schema
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin-only component
|
||||
* @dial-ignore
|
||||
*/
|
||||
export const AdminPanel: FC<AdminPanelProps> = ({ ... }) => {
|
||||
// This component won't appear in dial UI
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
This is useful for:
|
||||
|
||||
|
||||
|
||||
- Internal/utility components that shouldn't be exposed in the UI
|
||||
|
||||
- Admin-only or developer-only components
|
||||
|
||||
- Components that are still under development
|
||||
|
||||
- Helper components that are only used internally
|
||||
|
||||
|
||||
|
||||
When `@dial-ignore` is used at the class/interface level:
|
||||
|
||||
|
||||
|
||||
- The entire component is skipped during dial schema generation
|
||||
|
||||
- No properties from that component will appear in the dial UI
|
||||
|
||||
- Any child properties or nested interfaces are also excluded
|
||||
|
||||
|
||||
|
||||
## Custom Property Labels
|
||||
|
||||
|
||||
The `@dial-label` annotation allows you to specify custom labels for properties that will be displayed in the UI instead of the default auto-generated labels from the property name:
|
||||
|
||||
|
||||
```tsx
|
||||
interface ComponentProps {
|
||||
/**
|
||||
* Position in 3D space
|
||||
* @dial transform
|
||||
* @dial-dtype vector3
|
||||
* @dial-label 3D Position
|
||||
*/
|
||||
pos3d: [number, number, number];
|
||||
|
||||
/**
|
||||
* Background color
|
||||
* @dial appearance
|
||||
* @dial-dtype color
|
||||
* @dial-label Background Color
|
||||
*/
|
||||
bgColor: string;
|
||||
|
||||
/**
|
||||
* Enable shadows
|
||||
* @dial-dtype boolean
|
||||
* @dial-label Enable Shadow Rendering
|
||||
*/
|
||||
shadowsOn: boolean;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
In the generated UI:
|
||||
|
||||
|
||||
|
||||
- `pos3d` will display as "3D Position" instead of "Pos3d"
|
||||
|
||||
- `bgColor` will display as "Background Color" instead of "BgColor"
|
||||
|
||||
- `shadowsOn` will display as "Enable Shadow Rendering" instead of "ShadowsOn"
|
||||
|
||||
|
||||
|
||||
This is particularly useful when property names follow coding conventions (camelCase, abbreviations) but you want more user-friendly labels in the UI.
|
||||
|
||||
|
||||
## Complete Example
|
||||
|
||||
|
||||
Here's a complete example showing exclusion methods and custom labels:
|
||||
|
||||
|
||||
### Component Definition
|
||||
|
||||
|
||||
```tsx
|
||||
// Box3D.tsx
|
||||
interface Box3DProps {
|
||||
/**
|
||||
* Box dimensions
|
||||
* @dial geometry
|
||||
* @dial-dtype vector3
|
||||
* @dial-min 0.1
|
||||
* @dial-max 10
|
||||
* @dial-step 0.1
|
||||
*/
|
||||
size: [number, number, number];
|
||||
|
||||
/**
|
||||
* Position in 3D space
|
||||
* @dial transform
|
||||
* @dial-dtype vector3
|
||||
* @dial-min -100
|
||||
* @dial-max 100
|
||||
* @dial-step 0.5
|
||||
*/
|
||||
position: [number, number, number];
|
||||
|
||||
/**
|
||||
* Material color
|
||||
* @dial appearance
|
||||
* @dial-dtype color
|
||||
*/
|
||||
color: string;
|
||||
|
||||
/**
|
||||
* Opacity level
|
||||
* @dial appearance
|
||||
* @dial-min 0
|
||||
* @dial-max 1
|
||||
* @dial-step 0.01
|
||||
*/
|
||||
opacity: number;
|
||||
|
||||
// Properties to exclude:
|
||||
|
||||
/**
|
||||
* Internal mesh reference
|
||||
* @dial-ignore
|
||||
*/
|
||||
_meshRef?: THREE.Mesh;
|
||||
|
||||
/**
|
||||
* React className - will be excluded via CLI
|
||||
*/
|
||||
className?: string;
|
||||
|
||||
/**
|
||||
* React style - will be excluded via CLI
|
||||
*/
|
||||
style?: React.CSSProperties;
|
||||
|
||||
/**
|
||||
* Click handler - will be excluded via CLI pattern
|
||||
*/
|
||||
onClick?: () => void;
|
||||
|
||||
/**
|
||||
* Change handler - will be excluded via CLI pattern
|
||||
*/
|
||||
onChange?: (value: any) => void;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### CLI Commands
|
||||
|
||||
|
||||
```bash
|
||||
# Generate schema excluding React-specific props and handlers
|
||||
dial-cli -i className -i style -i "on*" Box3D.tsx
|
||||
|
||||
# Or using comma-separated list
|
||||
dial-cli --ignore className,style,onClick,onChange Box3D.tsx
|
||||
|
||||
# Exclude all private properties and event handlers
|
||||
dial-cli -i "_*" -i "on*" Box3D.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Generated Schema
|
||||
|
||||
|
||||
The generated schema will only include:
|
||||
|
||||
|
||||
|
||||
- `size` - Box dimensions control
|
||||
|
||||
- `position` - Position control
|
||||
|
||||
- `color` - Color picker
|
||||
|
||||
- `opacity` - Opacity slider
|
||||
|
||||
|
||||
|
||||
Excluded properties:
|
||||
|
||||
|
||||
|
||||
- `_meshRef` - Excluded by `@dial-ignore` annotation
|
||||
|
||||
- `className`, `style` - Excluded by CLI `-i` option
|
||||
|
||||
- `onClick`, `onChange` - Excluded by CLI pattern `"on*"`
|
||||
|
||||
|
||||
|
||||
## CLI Options Reference
|
||||
|
||||
|
||||
```bash
|
||||
dial-cli [options] <files...>
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
|
||||
| Option | Short | Description | Example |
|
||||
| `--output <dir>` | `-o` | Output directory for generated files | `-o ./schemas` |
|
||||
| `--ignore <prop>` | `-i` | Properties to exclude (supports glob) | `-i className -i "on*"` |
|
||||
| `--verbose` | | Enable verbose output | `--verbose` |
|
||||
| `--quiet` | | Suppress output except errors | `--quiet` |
|
||||
| `--help` | `-h` | Display help message | `--help` |
|
||||
| `--version` | `-v` | Display version | `--version` |
|
||||
|
||||
|
||||
|
||||
## Output Files
|
||||
|
||||
|
||||
The CLI generates files with a clean directory structure:
|
||||
|
||||
|
||||
**Main Output:**
|
||||
|
||||
|
||||
|
||||
- **`schema.dial`** - Combined schemas for all components, ready for UI generation
|
||||
|
||||
|
||||
|
||||
**Debug Output (verbose mode only):**
|
||||
|
||||
|
||||
|
||||
- **`debug/component-raw.json`** - Raw AST and JSDoc extraction
|
||||
|
||||
- **`debug/component-combined.json`** - Enhanced metadata with dial schemas
|
||||
|
||||
- **`debug/component-schemas.json`** - Individual component schemas
|
||||
|
||||
|
||||
|
||||
This structure keeps your main output directory clean while providing detailed debug information when needed.
|
||||
|
||||
|
||||
## Best Practices
|
||||
|
||||
|
||||
### 1. Combine Both Exclusion Methods
|
||||
|
||||
|
||||
Use `@dial-ignore` for properties that should never be exposed in the UI:
|
||||
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* @dial-ignore
|
||||
*/
|
||||
_internalState?: any;
|
||||
|
||||
```
|
||||
|
||||
|
||||
Use CLI `--ignore` for context-specific exclusions:
|
||||
|
||||
|
||||
```bash
|
||||
# Exclude React-specific props when generating for non-React environments
|
||||
dial-cli -i className -i style Component.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 2. Use Patterns for Consistency
|
||||
|
||||
|
||||
Create consistent naming conventions and use patterns:
|
||||
|
||||
|
||||
```bash
|
||||
# Exclude all private properties, refs, and handlers
|
||||
dial-cli -i "_*" -i "*Ref" -i "on*" Component.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 3. Create Build Scripts
|
||||
|
||||
|
||||
Add scripts to your `package.json`:
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"dial:generate": "dial-cli -o ./schemas -i className,style,key,ref src/components/*.tsx",
|
||||
"dial:generate:clean": "dial-cli -o ./schemas -i '_*,on*,*Ref,className,style' src/components/*.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 4. Document Excluded Properties
|
||||
|
||||
|
||||
When using `@dial-ignore`, add a comment explaining why:
|
||||
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* Internal cache for performance optimization
|
||||
* Not meant to be modified by users
|
||||
* @dial-ignore
|
||||
*/
|
||||
_cache?: Map<string, any>;
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Integration Example
|
||||
|
||||
|
||||
Here's how to use the generated schemas in your application:
|
||||
|
||||
|
||||
```tsx
|
||||
import { DialProvider, DialPanel } from '@vuer-ai/vuer-uikit';
|
||||
import allSchemas from './schemas/schema.dial';
|
||||
|
||||
function App() {
|
||||
const [props, setProps] = useState({
|
||||
size: [1, 1, 1],
|
||||
position: [0, 0, 0],
|
||||
color: '#ff0000',
|
||||
opacity: 1
|
||||
});
|
||||
|
||||
const handleValueChange = (name: string, value: any) => {
|
||||
setProps(prev => ({ ...prev, [name]: value }));
|
||||
};
|
||||
|
||||
// Get the specific component schema from the combined schema file
|
||||
const box3DSchema = allSchemas.find(s => s.component === 'Box3D');
|
||||
|
||||
return (
|
||||
<DialProvider schemas={[box3DSchema]} onValueChange={handleValueChange}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Canvas>
|
||||
<Box3D {...props} />
|
||||
</Canvas>
|
||||
<DialPanel schemas={[box3DSchema]} />
|
||||
</div>
|
||||
</DialProvider>
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
### Properties Not Being Excluded
|
||||
|
||||
|
||||
|
||||
1. **Check annotation syntax**: Ensure `@dial-ignore` is on its own line
|
||||
|
||||
1. **Check pattern syntax**: Use quotes for patterns with wildcards: `-i "*Style"`
|
||||
|
||||
1. **Check property names**: Property names are case-sensitive
|
||||
|
||||
|
||||
|
||||
### Generated Schema Is Empty
|
||||
|
||||
|
||||
|
||||
1. Ensure your interface has JSDoc comments with `@dial` annotations
|
||||
|
||||
1. Check that the TypeScript file exports the interface
|
||||
|
||||
1. Verify the file path is correct
|
||||
|
||||
|
||||
|
||||
### Build Errors
|
||||
|
||||
|
||||
|
||||
1. Ensure `@vuer-ai/dial-cli` is installed
|
||||
|
||||
1. Try using the full path: `node_modules/.bin/dial-cli` (if installed locally)
|
||||
|
||||
1. Check Node.js version (requires Node 14+)
|
||||
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
|
||||
The dial-cli tool provides flexible property exclusion through:
|
||||
|
||||
|
||||
|
||||
- **`@dial-ignore` annotation** - Permanent, code-level exclusion
|
||||
|
||||
- **`--ignore` CLI option** - Runtime, context-specific exclusion
|
||||
|
||||
- **Glob patterns** - Flexible pattern-based exclusion
|
||||
|
||||
|
||||
|
||||
Combine these features to create clean, focused UI schemas that expose only the properties users need to control.
|
||||
Reference in New Issue
Block a user