219 lines
7.1 KiB
PowerShell
219 lines
7.1 KiB
PowerShell
$typesContent = @'
|
|
export type PlatformType = "ANDROID" | "IOS";
|
|
|
|
export interface ComponentNode {
|
|
id: string;
|
|
name: string;
|
|
type: string;
|
|
icon?: string;
|
|
order?: number;
|
|
props: ComponentProps;
|
|
children?: ComponentNode[];
|
|
pageId?: {
|
|
id: string;
|
|
name: string;
|
|
};
|
|
}
|
|
|
|
export interface ComponentProps {
|
|
identifier: string;
|
|
developer_notes?: string;
|
|
api?: string;
|
|
state?: string;
|
|
api_action?: string;
|
|
className?: string;
|
|
dataVariable?: string;
|
|
}
|
|
|
|
export interface GlobalState {
|
|
leftPanel: ComponentNode[];
|
|
middlePanel: ComponentNode[];
|
|
rightPanel: ComponentNode | null;
|
|
selectedComponent: number;
|
|
rightComponentId: string;
|
|
selectedPageComponent: string;
|
|
copiedComponent: ComponentNode | null;
|
|
copiedPage: ComponentNode[];
|
|
selectedPageId: SelectedPageId;
|
|
disabledComponent: boolean;
|
|
}
|
|
|
|
export interface SelectedPageId {
|
|
id: string;
|
|
name: string;
|
|
}
|
|
'@
|
|
|
|
if (-not (Test-Path ".\src\types\global.ts")) {
|
|
New-Item -Path ".\src\types" -ItemType Directory -Force
|
|
Set-Content -Path ".\src\types\global.ts" -Value $typesContent -NoNewline
|
|
}
|
|
|
|
$patterns = @(
|
|
# Pattern 1: Add interface for components without props
|
|
@{
|
|
'Match' = '(?<!interface\s+\w+Props\s*{[\s\S]*?}\s*\n\s*)(?<!type\s+\w+Props\s*=\s*{[\s\S]*?}\s*\n\s*)const\s+(\w+)\s*=\s*\(\s*\)\s*=>'
|
|
'Replace' = "interface `$1Props {}`n`nconst `$1: React.FC<`$1Props> = () =>"
|
|
},
|
|
# Pattern 2: Add interface for components with destructured props
|
|
@{
|
|
'Match' = '(?<!interface\s+\w+Props\s*{[\s\S]*?}\s*\n\s*)(?<!type\s+\w+Props\s*=\s*{[\s\S]*?}\s*\n\s*)const\s+(\w+)\s*=\s*\(\s*{\s*([^}]*)\s*}\s*\)\s*=>'
|
|
'Replace' = {
|
|
param($matches)
|
|
$componentName = $matches[1]
|
|
$propsText = $matches[2]
|
|
$props = $propsText -split ',\s*' | Where-Object { $_ -match '\S' } | ForEach-Object {
|
|
$prop = $_ -replace '=.*$', '' -replace '//.*$', '' -replace '\s+$', '' -replace '^\s+', ''
|
|
if ($prop -match 'children') {
|
|
" $prop: ReactNode;"
|
|
}
|
|
elseif ($prop -match 'type') {
|
|
" $prop: PlatformType;"
|
|
}
|
|
elseif ($prop -match 'dispatch') {
|
|
" $prop: React.Dispatch<any>;"
|
|
}
|
|
elseif ($prop -match 'state') {
|
|
" $prop: GlobalState;"
|
|
}
|
|
elseif ($prop -match 'ref') {
|
|
" $prop?: React.RefObject<any>;"
|
|
}
|
|
elseif ($prop -match 'style') {
|
|
" $prop?: React.CSSProperties;"
|
|
}
|
|
elseif ($prop -match 'className') {
|
|
" $prop?: string;"
|
|
}
|
|
elseif ($prop -match 'onClick|onSubmit|onChange|onBlur|onFocus') {
|
|
" $prop?: (event: any) => void;"
|
|
}
|
|
elseif ($prop -match 'component') {
|
|
" $prop?: ComponentNode;"
|
|
}
|
|
elseif ($prop -match 'components|leftPanel|middlePanel') {
|
|
" $prop?: ComponentNode[];"
|
|
}
|
|
elseif ($prop -match 'componentId') {
|
|
" $prop?: string;"
|
|
}
|
|
elseif ($prop -match '\[\]$') {
|
|
" $prop?: ${prop};"
|
|
}
|
|
else {
|
|
" $prop?: any;"
|
|
}
|
|
}
|
|
$propsInterface = $props -join "`n"
|
|
@"
|
|
import { PlatformType, ComponentNode, GlobalState } from '@/types/global';
|
|
|
|
interface ${componentName}Props {
|
|
$propsInterface
|
|
}
|
|
|
|
const $componentName: React.FC<${componentName}Props> = ({
|
|
$propsText
|
|
}) =>
|
|
"@
|
|
}
|
|
},
|
|
# Pattern 3: Add React.FC type to memo wrapped components
|
|
@{
|
|
'Match' = 'export\s+default\s+memo\((\w+)\)'
|
|
'Replace' = 'export default memo($1) as React.FC<$1Props>'
|
|
},
|
|
# Pattern 4: Add return type to useEffect
|
|
@{
|
|
'Match' = 'useEffect\(\(\)\s*=>'
|
|
'Replace' = 'useEffect((): void =>'
|
|
},
|
|
# Pattern 5: Add type for state variables
|
|
@{
|
|
'Match' = 'useState\(([^)]+)\)'
|
|
'Replace' = {
|
|
param($matches)
|
|
$initialValue = $matches[1].Trim()
|
|
if ($initialValue -match '^\[\s*\]\s*$') {
|
|
'useState<ComponentNode[]>([])'
|
|
}
|
|
elseif ($initialValue -match '^\{\s*\}\s*$') {
|
|
'useState<Record<string, any>>({})'
|
|
}
|
|
elseif ($initialValue -match '^".*"$') {
|
|
'useState<string>(' + $initialValue + ')'
|
|
}
|
|
elseif ($initialValue -match '^\d+(\.\d+)?$') {
|
|
'useState<number>(' + $initialValue + ')'
|
|
}
|
|
elseif ($initialValue -match '^(true|false)$') {
|
|
'useState<boolean>(' + $initialValue + ')'
|
|
}
|
|
elseif ($initialValue -match '^null$') {
|
|
'useState<ComponentNode | null>(null)'
|
|
}
|
|
elseif ($initialValue -match '^undefined$') {
|
|
'useState<undefined>(undefined)'
|
|
}
|
|
else {
|
|
'useState<any>(' + $initialValue + ')'
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
$srcPath = ".\src"
|
|
$files = Get-ChildItem -Path $srcPath -Recurse -Include "*.tsx"
|
|
|
|
foreach ($file in $files) {
|
|
$content = Get-Content $file.FullName -Raw
|
|
$modified = $false
|
|
|
|
# Add necessary React imports if not present
|
|
$reactImports = @()
|
|
|
|
if (-not ($content -match '\bFC\b')) {
|
|
$reactImports += "FC"
|
|
}
|
|
if (-not ($content -match '\bReactNode\b')) {
|
|
$reactImports += "ReactNode"
|
|
}
|
|
if (-not ($content -match '\bCSSProperties\b') -and $content -match 'style\s*[?:]') {
|
|
$reactImports += "CSSProperties"
|
|
}
|
|
|
|
if ($reactImports.Count -gt 0) {
|
|
if ($content -match 'import\s+React,\s*{([^}]*?)}\s+from\s+[''"]react[''"]') {
|
|
$existingImports = $matches[1]
|
|
$newImports = ($reactImports | Where-Object { $existingImports -notmatch "\b$_\b" }) -join ", "
|
|
if ($newImports) {
|
|
$content = $content -replace 'import\s+React,\s*{([^}]*?)}\s+from\s+[''"]react[''"]', "import React, { `$1, $newImports } from 'react'"
|
|
$modified = $true
|
|
}
|
|
}
|
|
elseif ($content -match 'import\s+React\s+from\s+[''"]react[''"]') {
|
|
$content = $content -replace 'import\s+React\s+from\s+[''"]react[''"]', "import React, { $($reactImports -join ', ') } from 'react'"
|
|
$modified = $true
|
|
}
|
|
}
|
|
|
|
foreach ($pattern in $patterns) {
|
|
if ($content -match $pattern.Match) {
|
|
if ($pattern.Replace -is [scriptblock]) {
|
|
$content = [regex]::Replace($content, $pattern.Match, $pattern.Replace)
|
|
}
|
|
else {
|
|
$content = $content -replace $pattern.Match, $pattern.Replace
|
|
}
|
|
$modified = $true
|
|
}
|
|
}
|
|
|
|
if ($modified) {
|
|
Write-Host "Adding types to: $($file.FullName)"
|
|
$content | Set-Content $file.FullName -NoNewline
|
|
}
|
|
}
|
|
|
|
Write-Host "Done adding types to components and pages."
|