upd: routing dev

This commit is contained in:
2026-04-28 17:34:45 +08:00
parent 94724a5081
commit b03f267743
13 changed files with 2289 additions and 7 deletions

104
src/lib/schema-parser.ts Normal file
View File

@@ -0,0 +1,104 @@
export interface SchemaField {
name: string
type: string
isId: boolean
isUnique: boolean
isOptional: boolean
isList: boolean
isRelation: boolean
default?: string
}
export interface SchemaRelation {
from: string
fromField: string
to: string
toField: string
onDelete?: string
}
export interface SchemaModel {
name: string
tableName: string
fields: SchemaField[]
}
export interface SchemaEnum {
name: string
values: string[]
}
export interface ParsedSchema {
models: SchemaModel[]
enums: SchemaEnum[]
relations: SchemaRelation[]
}
export function parseSchema(raw: string): ParsedSchema {
const models: SchemaModel[] = []
const enums: SchemaEnum[] = []
const relations: SchemaRelation[] = []
const blocks = raw.match(/(model|enum)\s+(\w+)\s*\{([^}]*)}/gs) ?? []
for (const block of blocks) {
const match = block.match(/(model|enum)\s+(\w+)\s*\{([^}]*)}/s)
if (!match) continue
const [, type, name, body] = match
const lines = body
.split('\n')
.map((l) => l.trim())
.filter((l) => l && !l.startsWith('//'))
if (type === 'enum') {
enums.push({ name, values: lines })
continue
}
let tableName = name
const fields: SchemaField[] = []
for (const line of lines) {
const mapMatch = line.match(/@@map\("(\w+)"\)/)
if (mapMatch) { tableName = mapMatch[1]; continue }
if (line.startsWith('@@')) continue
const fieldMatch = line.match(/^(\w+)\s+(\w+)(\?)?(\[\])?\s*(.*)$/)
if (!fieldMatch) continue
const [, fName, fType, optional, list, attrs] = fieldMatch
const isId = attrs.includes('@id')
const isUnique = attrs.includes('@unique')
const isRelation = attrs.includes('@relation')
const defaultMatch = attrs.match(/@default\(([^)]+)\)/)
const isModelRef =
/^[A-Z]/.test(fType) &&
!enums.some((e) => e.name === fType) &&
!['String', 'Int', 'Float', 'Boolean', 'DateTime', 'BigInt', 'Decimal', 'Bytes', 'Json'].includes(fType)
if (isRelation) {
const relMatch = attrs.match(
/@relation\(fields:\s*\[(\w+)],\s*references:\s*\[(\w+)](?:,\s*onDelete:\s*(\w+))?\)/,
)
if (relMatch) {
relations.push({ from: name, fromField: relMatch[1], to: fType, toField: relMatch[2], onDelete: relMatch[3] })
}
}
fields.push({
name: fName,
type: fType + (list ? '[]' : ''),
isId, isUnique,
isOptional: !!optional,
isList: !!list,
isRelation: isModelRef,
default: defaultMatch?.[1],
})
}
models.push({ name, tableName, fields })
}
return { models, enums, relations }
}