{"version":3,"file":"generate-module.mjs","names":[],"sources":["../src/cli/generate-module.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport yargs from \"yargs\";\nimport {\n  hideBin,\n} from \"yargs/helpers\";\n\nimport {\n  GnoJSONRPCProvider,\n} from \"../provider/jsonrpc/jsonrpc.js\";\nimport {\n  FunctionSignature, NamedType,\n} from \"../provider/types/vm.js\";\n\nfunction gnoTypeToTS(gnoType: string): string {\n  switch (gnoType) {\n    case \"string\":\n      return \"string\";\n    case \"bool\":\n      return \"boolean\";\n    case \"int\":\n    case \"int64\":\n    case \"uint\":\n    case \"uint64\":\n      return \"bigint\";\n    case \"int8\":\n    case \"int16\":\n    case \"int32\":\n    case \"uint8\":\n    case \"uint16\":\n    case \"uint32\":\n    case \"float32\":\n    case \"float64\":\n    case \"byte\":\n    case \"rune\":\n      return \"number\";\n    case \"error\":\n      return \"string\";\n    default:\n      return \"unknown\";\n  }\n}\n\n/**\n * Returns true if the parameter is a VM-injected context (std.Caller)\n * that should not be exposed to the user.\n */\nfunction isContextParam(param: NamedType): boolean {\n  return param.Type.startsWith(\"interface {\");\n}\n\n/**\n * Sanitize a Gno parameter name into a valid TypeScript identifier.\n * The VM uses names like \".arg_0\" for unnamed params.\n */\nfunction sanitizeParamName(name: string): string {\n  // Strip leading dots / non-identifier characters\n  const cleaned = name.replace(/^[^a-zA-Z_$]+/, \"\");\n  return cleaned || \"arg\";\n}\n\n/**\n * Filter out VM-injected context parameters from a function's param list.\n */\nfunction filterUserParams(params: NamedType[] | null): NamedType[] {\n  if (!params) return [];\n  return params\n    .filter(p => !isContextParam(p))\n    .map(p => ({\n      ...p,\n      Name: sanitizeParamName(p.Name),\n    }));\n}\n\nfunction normalizeResults(results: NamedType[] | null): NamedType[] {\n  return results || [];\n}\n\nfunction realmPathToSegments(realmPath: string): string[] {\n  return realmPath\n    .replace(/^gno\\.land\\//, \"\")\n    .split(\"/\")\n    .filter(s => s.length > 0);\n}\n\n/**\n * Ensure the realm path has the gno.land prefix required by the VM.\n * Accepts both \"/r/demo/boards\" and \"gno.land/r/demo/boards\".\n */\nfunction normalizeRealmPath(realmPath: string): string {\n  if (realmPath.startsWith(\"/\")) {\n    return \"gno.land\" + realmPath;\n  }\n  return realmPath;\n}\n\nfunction buildReturnType(results: NamedType[]): string {\n  if (results.length === 0) {\n    return \"void\";\n  }\n  return \"[\" + results.map(r => gnoTypeToTS(r.Type)).join(\", \") + \"]\";\n}\n\nfunction buildParamsType(params: NamedType[]): string {\n  if (params.length === 0) {\n    return \"\";\n  }\n  const fields = params\n    .map(p => `${p.Name}: ${gnoTypeToTS(p.Type)}`)\n    .join(\"; \");\n  return `params: { ${fields} }`;\n}\n\nfunction buildEvalExpression(funcName: string, params: NamedType[]): string {\n  if (params.length === 0) {\n    return `\\`${funcName}()\\``;\n  }\n  const args = params\n    .map((p) => {\n      if (p.Type === \"string\") {\n        return `\"\\${params.${p.Name}}\"`;\n      }\n      return `\\${params.${p.Name}}`;\n    })\n    .join(\",\");\n  return `\\`${funcName}(${args})\\``;\n}\n\nfunction buildCallArgs(params: NamedType[]): string {\n  if (params.length === 0) {\n    return \"[]\";\n  }\n  const args = params.map(p => `String(params.${p.Name})`).join(\", \");\n  return `[${args}]`;\n}\n\nfunction generateModule(\n  realmPath: string,\n  signatures: FunctionSignature[],\n): string {\n  const segments = realmPathToSegments(realmPath);\n  const lines: string[] = [];\n\n  lines.push(\"/* eslint-disable max-lines-per-function */\");\n  lines.push(\"/* eslint-disable max-lines */\");\n  lines.push(\"// Auto-generated module for \" + realmPath + \" — DO NOT EDIT\");\n  // Imports\n  lines.push(\n    \"import { TransactionEndpoint, TxFee } from \\\"@gnolang/tm2-js-client\\\";\",\n  );\n  lines.push(\"import { GnoWallet } from \\\"@gnolang/gno-js-client\\\";\");\n  lines.push(\"// Imported with leading underscore to avoid linting errors about unused imports in void-returning functions\");\n  lines.push(\n    \"import { parseGnoReturns as _parseGnoReturns } from \\\"@gnolang/gno-js-client\\\";\",\n  );\n  lines.push(\"\");\n\n  // Realm path constant\n  lines.push(`const realm = \"${realmPath}\";`);\n  lines.push(\"\");\n\n  // Pre-process signatures: filter context params and normalize results\n  const processed = signatures.map(sig => ({\n    ...sig,\n    Params: filterUserParams(sig.Params),\n    Results: normalizeResults(sig.Results),\n  }));\n\n  // Return type aliases\n  for (const sig of processed) {\n    const returnType = buildReturnType(sig.Results);\n    if (returnType !== \"void\") {\n      lines.push(`type ${sig.FuncName}Return = ${returnType};`);\n    }\n  }\n  lines.push(\"\");\n\n  // queryClient\n  lines.push(\"const queryClient = (wallet: GnoWallet) => {\");\n  lines.push(\"\\treturn {\");\n  for (let i = 0; i < processed.length; i++) {\n    const sig = processed[i];\n    const paramsType = buildParamsType(sig.Params);\n    const returnType = buildReturnType(sig.Results);\n    const hasReturn = returnType !== \"void\";\n    const returnTypeStr = hasReturn ? `${sig.FuncName}Return` : \"void\";\n    const evalExpr = buildEvalExpression(sig.FuncName, sig.Params);\n\n    const paramsList = paramsType\n      ? `${paramsType}, height?: number`\n      : \"height?: number\";\n\n    lines.push(\n      `\\t\\tasync ${sig.FuncName}(${paramsList}):Promise<${returnTypeStr}> {`,\n    );\n    if (hasReturn) {\n      lines.push(\n        `\\t\\t\\tconst result = await wallet.getProvider().evaluateExpression(realm, ${evalExpr}, height);`,\n      );\n      lines.push(`\\t\\t\\treturn _parseGnoReturns(result) as ${returnTypeStr};`);\n    }\n    else {\n      lines.push(\n        `\\t\\t\\tawait wallet.getProvider().evaluateExpression(realm, ${evalExpr}, height);`,\n      );\n      lines.push(\"\\t\\t\\treturn;\");\n    }\n    lines.push(\"\\t\\t}\" + (i < processed.length - 1 ? \",\" : \"\"));\n  }\n  lines.push(\"\\t}\");\n  lines.push(\"}\");\n  lines.push(\"\");\n\n  // txClient\n  lines.push(\"const txClient = (wallet: GnoWallet) => {\");\n  lines.push(\"\\treturn {\");\n  for (let i = 0; i < processed.length; i++) {\n    const sig = processed[i];\n    const paramsType = buildParamsType(sig.Params);\n    const returnType = buildReturnType(sig.Results);\n    const hasReturn = returnType !== \"void\";\n    const returnTypeStr = hasReturn ? `${sig.FuncName}Return` : \"void\";\n    const callArgs = buildCallArgs(sig.Params);\n\n    const paramsList = paramsType\n      ? `${paramsType}, funds: Map<string, number>, maxDeposit: Map<string, number>, fee: TxFee`\n      : \"funds: Map<string, number>, maxDeposit: Map<string, number>, fee: TxFee\";\n\n    lines.push(\n      `\\t\\tasync ${sig.FuncName}(${paramsList}):Promise<${returnTypeStr}> {`,\n    );\n    lines.push(\"\\t\\t\\tconst resp = await wallet.callMethod(\");\n    lines.push(\"\\t\\t\\t\\trealm,\");\n    lines.push(`\\t\\t\\t\\t\"${sig.FuncName}\",`);\n    lines.push(`\\t\\t\\t\\t${callArgs},`);\n    lines.push(\"\\t\\t\\t\\tTransactionEndpoint.BROADCAST_TX_COMMIT,\");\n    lines.push(\"\\t\\t\\t\\tfunds,\");\n    lines.push(\"\\t\\t\\t\\tmaxDeposit,\");\n    lines.push(\"\\t\\t\\t\\tfee\");\n    lines.push(\"\\t\\t\\t);\");\n    lines.push(\"\\t\\t\\tif (resp.deliver_tx.ResponseBase.Error) {\");\n    lines.push(\n      \"\\t\\t\\t\\tthrow new Error(resp.deliver_tx.ResponseBase.Log || JSON.stringify(resp.deliver_tx.ResponseBase.Error));\",\n    );\n    lines.push(\"\\t\\t\\t}\");\n    if (hasReturn) {\n      lines.push(\n        \"\\t\\t\\tconst result = atob(resp.deliver_tx.ResponseBase.Data as string);\",\n      );\n      lines.push(`\\t\\t\\treturn _parseGnoReturns(result) as ${returnTypeStr};`);\n    }\n    lines.push(\"\\t\\t}\" + (i < processed.length - 1 ? \",\" : \"\"));\n  }\n  lines.push(\"\\t}\");\n  lines.push(\"}\");\n  lines.push(\"\");\n\n  // RealmModule class\n  lines.push(\"class RealmModule {\");\n  lines.push(\"\\tpublic query: ReturnType<typeof queryClient>;\");\n  lines.push(\"\\tpublic tx: ReturnType<typeof txClient>;\");\n  lines.push(\"\");\n  lines.push(\"\\tconstructor(wallet: GnoWallet) {\");\n  lines.push(\"\\t\\tthis.tx = txClient(wallet);\");\n  lines.push(\"\\t\\tthis.query = queryClient(wallet);\");\n  lines.push(\"\\t}\");\n  lines.push(\"}\");\n  lines.push(\"\");\n\n  // Factory function — build nested realms object from path segments\n  const opening = segments.map(seg => `{ ${seg}: `).join(\"\");\n  const closing = \" }\".repeat(segments.length);\n  lines.push(\"const Realm = (wallet: GnoWallet) => {\");\n  lines.push(\"\\treturn {\");\n  lines.push(\n    `\\t\\trealm: { realms: ${opening}new RealmModule(wallet)${closing} }`,\n  );\n  lines.push(\"\\t}\");\n  lines.push(\"}\");\n  lines.push(\"\");\n  lines.push(\"export default Realm;\");\n  lines.push(\"\");\n\n  return lines.join(\"\\n\");\n}\n\nasync function generateAndWrite(\n  provider: GnoJSONRPCProvider,\n  realmPath: string,\n  outRoot: string,\n): Promise<boolean> {\n  console.log(`Fetching function signatures for ${realmPath}...`);\n  let signatures: FunctionSignature[];\n  try {\n    signatures = await provider.getFunctionSignatures(realmPath);\n  }\n  catch (err: unknown) {\n    const msg = err instanceof Error ? err.message : String(err);\n    throw new Error(\n      `Failed to fetch function signatures for \"${realmPath}\" from provider:\\n  ${msg}\\n\\nPlease verify:\\n  - The realm path \"${realmPath}\" exists on the chain`,\n      {\n        cause: err,\n      });\n  }\n  if (!signatures || signatures.length === 0) {\n    console.log(\"  No exported functions, skipping.\");\n    return false;\n  }\n  console.log(`  ${signatures.length} function(s) found.`);\n\n  const code = generateModule(realmPath, signatures);\n  const segments = realmPathToSegments(realmPath);\n  const outDir = path.join(outRoot, ...segments);\n  fs.mkdirSync(outDir, {\n    recursive: true,\n  });\n  const outFile = path.join(outDir, \"module.ts\");\n  fs.writeFileSync(outFile, code, \"utf-8\");\n  console.log(`  Written to ${outFile}`);\n  return true;\n}\n\nfunction writeIndex(outRoot: string, realmPaths: string[]): void {\n  const lines: string[] = [];\n  for (const realmPath of realmPaths) {\n    const segments = realmPathToSegments(realmPath);\n    const alias = segments.join(\"_\");\n    const importPath = \"./\" + segments.join(\"/\") + \"/module.js\";\n    lines.push(`export { default as ${alias} } from '${importPath}';`);\n  }\n  lines.push(\"\");\n  const outFile = path.join(outRoot, \"index.ts\");\n  fs.writeFileSync(outFile, lines.join(\"\\n\"), \"utf-8\");\n  console.log(`\\nIndex written to ${outFile}`);\n}\n\nasync function main() {\n  const argv = await yargs(hideBin(process.argv))\n    .option(\"realm\", {\n      type: \"string\",\n      describe: \"Realm path, e.g. gno.land/r/demo/boards or /r/demo/boards\",\n    })\n    .option(\"prefix\", {\n      type: \"string\",\n      describe:\n        \"Path prefix — generate modules for all realms under this path, e.g. /r/gnoland\",\n    })\n    .option(\"remote\", {\n      type: \"string\",\n      demandOption: true,\n      describe: \"JSON-RPC endpoint URL, e.g. http://localhost:26657\",\n    })\n    .option(\"out\", {\n      type: \"string\",\n      default: \".\",\n      describe: \"Root output directory\",\n    })\n    .check((argv) => {\n      if (argv.realm && argv.prefix) {\n        throw new Error(\"--realm and --prefix are mutually exclusive\");\n      }\n      return true;\n    })\n    .help()\n    .parseAsync();\n\n  const provider = await GnoJSONRPCProvider.create(argv.remote);\n\n  const generated: string[] = [];\n\n  if (argv.realm) {\n    const realmPath = normalizeRealmPath(argv.realm);\n    if (await generateAndWrite(provider, realmPath, argv.out)) {\n      generated.push(realmPath);\n    }\n  }\n  else {\n    const prefix = argv.prefix\n      ? normalizeRealmPath(argv.prefix)\n      : \"gno.land/r/\";\n    console.log(`Discovering realms under ${prefix}...`);\n    const realmPaths = await provider.getRealmPaths(prefix);\n    if (realmPaths.length === 0) {\n      console.log(\"No realms found.\");\n      return;\n    }\n    console.log(`Found ${realmPaths.length} realm(s).\\n`);\n    for (const realmPath of realmPaths) {\n      try {\n        if (await generateAndWrite(provider, realmPath, argv.out)) {\n          generated.push(realmPath);\n        }\n      }\n      catch (err: unknown) {\n        const msg = err instanceof Error ? err.message : String(err);\n        console.error(`  Skipping ${realmPath}: ${msg}`);\n      }\n    }\n  }\n\n  if (generated.length > 0) {\n    writeIndex(argv.out, generated);\n  }\n}\n\nmain().catch((err) => {\n  console.error(\"Error:\", err.message || err);\n  process.exit(1);\n});\n"],"mappings":"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"}