Add identifier sanitization for Flask generators

This commit is contained in:
2026-01-18 17:58:01 +00:00
parent 91969e8494
commit 2641793e0f
3 changed files with 34 additions and 8 deletions

View File

@@ -1,5 +1,6 @@
import { FlaskConfig } from '@/types/project'
import { generateFlaskBlueprint } from './generateFlaskBlueprint'
import { sanitizeIdentifier } from './sanitizeIdentifier'
export function generateFlaskApp(config: FlaskConfig): Record<string, string> {
const files: Record<string, string> = {}
@@ -11,7 +12,7 @@ export function generateFlaskApp(config: FlaskConfig): Record<string, string> {
appCode += `\n`
config.blueprints.forEach(blueprint => {
const blueprintVarName = blueprint.name.toLowerCase().replace(/\s+/g, '_')
const blueprintVarName = sanitizeIdentifier(blueprint.name, { fallback: 'blueprint' })
appCode += `from blueprints.${blueprintVarName} import ${blueprintVarName}_bp\n`
})
@@ -34,7 +35,7 @@ export function generateFlaskApp(config: FlaskConfig): Record<string, string> {
}
config.blueprints.forEach(blueprint => {
const blueprintVarName = blueprint.name.toLowerCase().replace(/\s+/g, '_')
const blueprintVarName = sanitizeIdentifier(blueprint.name, { fallback: 'blueprint' })
appCode += ` app.register_blueprint(${blueprintVarName}_bp)\n`
})
@@ -50,7 +51,7 @@ export function generateFlaskApp(config: FlaskConfig): Record<string, string> {
files['app.py'] = appCode
config.blueprints.forEach(blueprint => {
const blueprintVarName = blueprint.name.toLowerCase().replace(/\s+/g, '_')
const blueprintVarName = sanitizeIdentifier(blueprint.name, { fallback: 'blueprint' })
files[`blueprints/${blueprintVarName}.py`] = generateFlaskBlueprint(blueprint)
})

View File

@@ -1,14 +1,15 @@
import { FlaskBlueprint } from '@/types/project'
import { sanitizeIdentifier } from './sanitizeIdentifier'
export function generateFlaskBlueprint(blueprint: FlaskBlueprint): string {
let code = `from flask import Blueprint, request, jsonify\n`
code += `from typing import Dict, Any\n\n`
const blueprintVarName = blueprint.name.toLowerCase().replace(/\s+/g, '_')
const blueprintVarName = sanitizeIdentifier(blueprint.name, { fallback: 'blueprint' })
code += `${blueprintVarName}_bp = Blueprint('${blueprintVarName}', __name__, url_prefix='${blueprint.urlPrefix}')\n\n`
blueprint.endpoints.forEach(endpoint => {
const functionName = endpoint.name.toLowerCase().replace(/\s+/g, '_')
const functionName = sanitizeIdentifier(endpoint.name, { fallback: 'endpoint' })
code += `@${blueprintVarName}_bp.route('${endpoint.path}', methods=['${endpoint.method}'])\n`
code += `def ${functionName}():\n`
code += ` """\n`
@@ -31,13 +32,14 @@ export function generateFlaskBlueprint(blueprint: FlaskBlueprint): string {
if (endpoint.queryParams && endpoint.queryParams.length > 0) {
endpoint.queryParams.forEach(param => {
const paramVarName = sanitizeIdentifier(param.name, { fallback: 'param' })
if (param.required) {
code += ` ${param.name} = request.args.get('${param.name}')\n`
code += ` if ${param.name} is None:\n`
code += ` ${paramVarName} = request.args.get('${param.name}')\n`
code += ` if ${paramVarName} is None:\n`
code += ` return jsonify({'error': '${param.name} is required'}), 400\n\n`
} else {
const defaultVal = param.defaultValue || (param.type === 'string' ? "''" : param.type === 'number' ? '0' : 'None')
code += ` ${param.name} = request.args.get('${param.name}', ${defaultVal})\n`
code += ` ${paramVarName} = request.args.get('${param.name}', ${defaultVal})\n`
}
})
code += `\n`

View File

@@ -0,0 +1,23 @@
type SanitizeIdentifierOptions = {
fallback?: string
}
export function sanitizeIdentifier(value: string, options: SanitizeIdentifierOptions = {}): string {
const fallback = options.fallback ?? 'identifier'
const trimmed = value.trim()
const normalized = trimmed
.toLowerCase()
.replace(/[^a-z0-9_]+/g, '_')
.replace(/^_+|_+$/g, '')
.replace(/_+/g, '_')
if (!normalized) {
return fallback
}
if (/^[0-9]/.test(normalized)) {
return `_${normalized}`
}
return normalized
}