{"version":3,"file":"index.mjs","names":["comments: string[]","currentFn: ClaridocItem | undefined","contract: ClaridocContract","fn","curParam: string | undefined","parsed: Comments","arg"],"sources":["../src/index.ts"],"sourcesContent":["/** biome-ignore-all lint/style/useTrimStartEnd: suppressed */\nimport type {\n  ClarityAbi,\n  ClarityAbiArg,\n  ClarityAbiFunction,\n  ClarityAbiMap,\n  ClarityAbiVariable,\n} from '@clarigen/core';\n\nexport const FN_TYPES = ['read-only', 'public', 'private'] as const;\n\nexport const VAR_TYPES = ['map', 'data-var', 'constant'] as const;\n\ntype ClarityAbiItem = ClarityAbiFunction | ClarityAbiMap | ClarityAbiVariable;\n\ntype ClaridocItemType<T extends ClarityAbiItem> = {\n  abi: T;\n  comments: Comments;\n  startLine: number;\n  source: string[];\n};\n\nexport type ClaridocFunction = ClaridocItemType<ClarityAbiFunction>;\nexport type ClaridocMap = ClaridocItemType<ClarityAbiMap>;\nexport type ClaridocVariable = ClaridocItemType<ClarityAbiVariable>;\n\nexport type ClaridocItem = {\n  abi: ClarityAbiItem;\n  comments: Comments;\n  startLine: number;\n  source: string[];\n};\n// export type ClaridocItem = ClaridocFunction | ClaridocMap | ClaridocVariable;\n\nexport type Comments = {\n  params: Record<string, ClaridocParam>;\n  text: string[];\n};\n\nexport type ClaridocContract = {\n  functions: ClaridocFunction[];\n  maps: ClaridocMap[];\n  variables: ClaridocVariable[];\n  comments: string[];\n};\n\nexport type ClaridocParam = {\n  abi: ClarityAbiArg;\n  comments: string[];\n};\n\nexport function createContractDocInfo({\n  contractSrc,\n  abi,\n}: {\n  contractSrc: string;\n  abi: ClarityAbi;\n}): ClaridocContract {\n  const lines = contractSrc.split('\\n');\n  let comments: string[] = [];\n  let parensCount = 0;\n  let currentFn: ClaridocItem | undefined;\n  // const functions: ClaridocFunction[] = [];\n  const contract: ClaridocContract = {\n    comments: [],\n    functions: [],\n    variables: [],\n    maps: [],\n  };\n  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: ignored using `--suppress`\n  lines.forEach((line, lineNumber) => {\n    // Are we processing a function?\n    if (currentFn) {\n      currentFn.source.push(line);\n      parensCount = traceParens(line, parensCount);\n      if (parensCount === 0) {\n        // end of fn\n        pushItem(contract, currentFn);\n        // contract.functions.push(currentFn);\n        currentFn = undefined;\n      }\n      return;\n    }\n    // Are we gathering comments?\n    if (isComment(line)) {\n      const comment = line.replace(/^\\s*;;\\s*/g, '');\n      if (contract.comments.length === lineNumber) {\n        // Top-level contract comments\n        contract.comments.push(comment);\n      } else {\n        // Aggregate for a function\n        comments.push(comment);\n      }\n      return;\n    }\n\n    // Is this the start of a fn?\n    // const name = getFnName(line);\n    const name = findItemNameFromLine(line);\n    if (typeof name === 'undefined') {\n      // Not a comment or fn start, clear comments.\n      comments = [];\n    } else {\n      // New function found.\n      // const abiFn = abi.functions.find((fn) => {\n      //   return fn.name === name;\n      // })\n      const abiFn = findAbiItemByName(abi, name);\n      if (!abiFn) {\n        console.debug(\n          `[claridoc]: Unable to find ABI for function \\`${name}\\`. Probably a bug.`\n        );\n        return;\n      }\n      parensCount = traceParens(line, 0);\n      const metaComments = parseComments(comments, abiFn);\n      currentFn = {\n        abi: abiFn,\n        comments: metaComments,\n        startLine: lineNumber,\n        source: [line],\n      };\n      if (parensCount === 0) {\n        // end of fn - single line fn\n        // contract.functions.push(currentFn);\n        pushItem(contract, currentFn);\n        currentFn = undefined;\n      }\n      comments = [];\n    }\n  });\n  return contract;\n}\n\nfunction pushItem(contract: ClaridocContract, item: ClaridocItem) {\n  if ('args' in item.abi) {\n    contract.functions.push(item as ClaridocFunction);\n  } else if ('key' in item.abi) {\n    contract.maps.push(item as ClaridocMap);\n  } else if ('access' in item.abi) {\n    contract.variables.push(item as ClaridocVariable);\n  }\n}\n\nfunction clarityNameMatcher(line: string) {\n  // biome-ignore lint/performance/useTopLevelRegex: ignored using `--suppress`\n  return /[\\w|\\-|?|!]+/.exec(line);\n}\n\nfunction findItemNameFromLine(line: string): string | undefined {\n  const fnType = FN_TYPES.find((type) => line.startsWith(`(define-${type}`));\n  if (fnType) {\n    const prefix = `(define-${fnType} (`;\n    const startString = line.slice(prefix.length);\n    const match = clarityNameMatcher(startString);\n    if (!match) {\n      console.debug(\n        `[claridocs]: Unable to determine function name from line:\\n  \\`${line}\\``\n      );\n      return;\n    }\n    return match[0];\n  }\n  for (const type of VAR_TYPES) {\n    const prefix = `(define-${type} `;\n    if (!line.startsWith(prefix)) continue;\n\n    const startString = line.slice(prefix.length);\n    const match = clarityNameMatcher(startString);\n    if (!match) {\n      console.debug(\n        `[claridocs]: Unable to determine ${type} name from line:\\n  \\`${line}\\``\n      );\n      return;\n    }\n    return match[0];\n  }\n  return;\n}\n\nfunction findAbiItemByName(\n  abi: ClarityAbi,\n  name: string\n): ClarityAbiItem | undefined {\n  // biome-ignore lint/nursery/noShadow: ignored using `--suppress`\n  const fn = abi.functions.find((fn) => fn.name === name);\n  if (fn) return fn;\n  const map = abi.maps.find((m) => m.name === name);\n  if (map) return map;\n  // biome-ignore lint/nursery/noShadow: ignored using `--suppress`\n  const v = abi.variables.find((v) => v.name === name);\n  return v;\n}\n\nexport function isComment(line: string) {\n  return line.startsWith(';;');\n}\n\nexport function getFnName(line: string) {\n  const fnType = FN_TYPES.find((type) => line.startsWith(`(define-${type}`));\n  if (typeof fnType === 'undefined') return;\n  const prefix = `(define-${fnType} (`;\n  const startString = line.slice(prefix.length);\n  const match = clarityNameMatcher(startString);\n  if (!match) {\n    console.debug(\n      `[claridocs]: Unable to determine function name from line:\\n  \\`${line}\\``\n    );\n    return;\n  }\n  return match[0];\n}\n\nexport function traceParens(line: string, count: number) {\n  let newCount = count;\n  // biome-ignore lint/complexity/noForEach: ignored using `--suppress`\n  line.split('').forEach((char) => {\n    // biome-ignore lint/nursery/noIncrementDecrement: ignored using `--suppress`\n    if (char === '(') newCount++;\n    // biome-ignore lint/nursery/noIncrementDecrement: ignored using `--suppress`\n    if (char === ')') newCount--;\n  });\n  return newCount;\n}\n\nexport function parseComments(\n  comments: string[],\n  abi: ClarityAbiItem\n): Comments {\n  // const params: Record<string, ClaridocParam> = {};\n  let curParam: string | undefined;\n  // const newComments: string[] = [];\n  const parsed: Comments = {\n    text: [],\n    params: {},\n  };\n  // biome-ignore lint/complexity/noForEach: ignored using `--suppress`\n  comments.forEach((line) => {\n    // biome-ignore lint/performance/useTopLevelRegex: ignored using `--suppress`\n    const paramMatches = /\\s*@param\\s([\\w|-]+)([;|-|\\s]*)(.*)/.exec(line);\n\n    if (paramMatches === null) {\n      if (!curParam || line.trim() === '') {\n        curParam = undefined;\n        parsed.text.push(line);\n      } else {\n        parsed.params[curParam].comments.push(line);\n      }\n      return;\n    }\n\n    if (!('args' in abi)) return;\n    const [_full, name, _separator, rest] = paramMatches;\n    // biome-ignore lint/nursery/noShadow: ignored using `--suppress`\n    const arg = abi.args.find((arg) => arg.name === name);\n    if (!arg) {\n      console.debug(`[claridocs]: Unable to find ABI for @param ${name}`);\n      return;\n    }\n    curParam = name;\n    parsed.params[curParam] = {\n      abi: arg,\n      comments: [rest],\n    };\n  });\n\n  if ('args' in abi) {\n    // biome-ignore lint/complexity/noForEach: ignored using `--suppress`\n    abi.args.forEach((arg) => {\n      if (!parsed.params[arg.name]) {\n        parsed.params[arg.name] = {\n          abi: arg,\n          comments: [],\n        };\n      }\n    });\n  }\n\n  return parsed;\n}\n"],"mappings":"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"}