{"version":3,"file":"command-file.mjs","names":[],"sources":["../../../src/codegen/generators/command-file.ts"],"sourcesContent":["import { fieldMetaToCode } from '../schema-to-code.ts';\nimport type { CodeBuilder, CommandMeta, FieldMeta, GeneratorContext } from '../types.ts';\n\nconst JS_RESERVED = new Set([\n  'break',\n  'case',\n  'catch',\n  'continue',\n  'debugger',\n  'default',\n  'delete',\n  'do',\n  'else',\n  'export',\n  'extends',\n  'finally',\n  'for',\n  'function',\n  'if',\n  'import',\n  'in',\n  'instanceof',\n  'new',\n  'return',\n  'super',\n  'switch',\n  'this',\n  'throw',\n  'try',\n  'typeof',\n  'var',\n  'void',\n  'while',\n  'with',\n  'yield',\n  'class',\n  'const',\n  'enum',\n  'let',\n  'static',\n  'implements',\n  'interface',\n  'package',\n  'private',\n  'protected',\n  'public',\n  'await',\n  'async',\n]);\n\n/** Convert a command name to a safe JS identifier (camelCase, reserved-word-safe). */\nexport function toSafeIdentifier(name: string): string {\n  const camel = name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\n  if (/^\\d/.test(camel)) return `_${camel}`;\n  if (JS_RESERVED.has(camel)) return `_${camel}`;\n  return camel;\n}\n\n/** Build the exported function name for a command (e.g. 'repo' → 'repoCommand'). */\nexport function toCommandFunctionName(name: string): string {\n  return `${toSafeIdentifier(name)}Command`;\n}\n\nexport interface CommandFileOptions {\n  /** Wrap config: generates .wrap() instead of .action(). */\n  wrap?: {\n    /** The external command to wrap (e.g. 'gh'). */\n    command: string;\n    /** Fixed args preceding the options (e.g. ['pr', 'list']). */\n    args?: string[];\n  };\n  /** Subcommand references to wire into this command via .command() calls. */\n  subcommands?: { name: string; varName: string; importPath: string; aliases?: string[] }[];\n}\n\n/**\n * Generate a single Padrone command file from a CommandMeta.\n * Produces a named function that chains .configure(), .arguments(), and .wrap() or .action().\n */\nexport function generateCommandFile(command: CommandMeta, ctx: GeneratorContext, options?: CommandFileOptions): CodeBuilder {\n  const code = ctx.createCodeBuilder();\n\n  const hasArgs = (command.arguments && command.arguments.length > 0) || (command.positionals && command.positionals.length > 0);\n\n  if (hasArgs) {\n    code.import('z', 'zod/v4');\n  }\n\n  code.importType('AnyPadroneBuilder', 'padrone');\n\n  // Import subcommand modules\n  if (options?.subcommands) {\n    for (const sub of options.subcommands) {\n      code.import([sub.varName], sub.importPath);\n    }\n  }\n\n  code.line();\n\n  if (command.deprecated) {\n    const msg = typeof command.deprecated === 'string' ? command.deprecated : 'This command is deprecated';\n    code.comment(`@deprecated ${msg}`);\n  }\n\n  const fnName = toCommandFunctionName(command.name);\n  code.line(`export function ${fnName}<T extends AnyPadroneBuilder>(cmd: T) {`);\n  code.line(`  return cmd`);\n\n  // .configure()\n  const configParts: string[] = [];\n  if (command.description) {\n    configParts.push(`description: ${JSON.stringify(command.description)}`);\n  }\n  if (command.deprecated) {\n    configParts.push(`deprecated: ${typeof command.deprecated === 'string' ? JSON.stringify(command.deprecated) : 'true'}`);\n  }\n  if (configParts.length > 0) {\n    code.line(`    .configure({ ${configParts.join(', ')} })`);\n  }\n\n  // .arguments()\n  if (hasArgs) {\n    const allFields = [...(command.arguments || []), ...(command.positionals || [])];\n    const schemaCode = fieldMetaToCode(allFields);\n\n    const positionalNames = (command.positionals || []).map((p) => (p.type === 'array' ? `'...${p.name}'` : `'${p.name}'`));\n    const fieldsMap = buildFieldsMap(allFields);\n    const hasMetaOptions = positionalNames.length > 0 || fieldsMap;\n\n    if (hasMetaOptions) {\n      code.line(`    .arguments(${schemaCode.code}, {`);\n      if (positionalNames.length > 0) {\n        code.line(`      positional: [${positionalNames.join(', ')}],`);\n      }\n      if (fieldsMap) {\n        code.line(`      fields: ${fieldsMap},`);\n      }\n      code.line(`    })`);\n    } else {\n      code.line(`    .arguments(${schemaCode.code})`);\n    }\n  }\n\n  // .command() calls for subcommands\n  if (options?.subcommands) {\n    for (const sub of options.subcommands) {\n      const nameArg =\n        sub.aliases && sub.aliases.length > 0\n          ? `[${JSON.stringify(sub.name)}, ${sub.aliases.map((a) => JSON.stringify(a)).join(', ')}]`\n          : JSON.stringify(sub.name);\n      code.line(`    .command(${nameArg}, ${sub.varName})`);\n    }\n  }\n\n  // .wrap() or .action()\n  if (options?.wrap) {\n    const wrapParts: string[] = [];\n    wrapParts.push(`command: ${JSON.stringify(options.wrap.command)}`);\n    if (options.wrap.args && options.wrap.args.length > 0) {\n      wrapParts.push(`args: [${options.wrap.args.map((a) => JSON.stringify(a)).join(', ')}]`);\n    }\n    code.line(`    .wrap({ ${wrapParts.join(', ')} })`);\n  } else {\n    code.line(`    .action((args) => { /* TODO */ })`);\n  }\n\n  code.line(`}`);\n\n  return code;\n}\n\nfunction buildFieldsMap(fields: FieldMeta[]): string | null {\n  const entries: string[] = [];\n  for (const field of fields) {\n    if (field.aliases && field.aliases.length > 0) {\n      // Split into flags (single-char) and aliases (multi-char)\n      const singleChar = field.aliases.filter((a) => a.replace(/^-+/, '').length === 1).map((a) => a.replace(/^-+/, ''));\n      const multiChar = field.aliases.filter((a) => a.replace(/^-+/, '').length > 1).map((a) => a.replace(/^-+/, ''));\n\n      const key = /^[a-zA-Z_$][\\w$]*$/.test(field.name) ? field.name : JSON.stringify(field.name);\n      const parts: string[] = [];\n      if (singleChar.length > 0) {\n        const flags = singleChar.length === 1 ? JSON.stringify(singleChar[0]) : `[${singleChar.map((a) => JSON.stringify(a)).join(', ')}]`;\n        parts.push(`flags: ${flags}`);\n      }\n      if (multiChar.length > 0) {\n        const alias = multiChar.length === 1 ? JSON.stringify(multiChar[0]) : `[${multiChar.map((a) => JSON.stringify(a)).join(', ')}]`;\n        parts.push(`alias: ${alias}`);\n      }\n      if (parts.length > 0) {\n        entries.push(`${key}: { ${parts.join(', ')} }`);\n      }\n    }\n  }\n  if (entries.length === 0) return null;\n  return `{ ${entries.join(', ')} }`;\n}\n"],"mappings":"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"}