Update
This commit is contained in:
+218
@@ -0,0 +1,218 @@
|
||||
$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."
|
||||
Reference in New Issue
Block a user