This commit is contained in:
Possible
2025-02-28 20:42:24 +01:00
parent de3a3a8ce4
commit ff0b919d62
932 changed files with 127824 additions and 4703 deletions
+218
View File
@@ -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."