@haneullabs/codegen 0.1.0 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +138 -33
  2. package/README.md +40 -38
  3. package/dist/bin/bash-complete.d.mts +6 -0
  4. package/dist/bin/bash-complete.d.mts.map +1 -0
  5. package/dist/bin/bash-complete.mjs +29 -0
  6. package/dist/bin/bash-complete.mjs.map +1 -0
  7. package/dist/bin/cli.d.mts +1 -0
  8. package/dist/bin/cli.mjs +24 -0
  9. package/dist/bin/cli.mjs.map +1 -0
  10. package/dist/cli/cli.mjs +28 -0
  11. package/dist/cli/cli.mjs.map +1 -0
  12. package/dist/cli/commands/generate/command.mjs +90 -0
  13. package/dist/cli/commands/generate/command.mjs.map +1 -0
  14. package/dist/cli/commands/generate/impl.mjs +72 -0
  15. package/dist/cli/commands/generate/impl.mjs.map +1 -0
  16. package/dist/cli/context.mjs +17 -0
  17. package/dist/cli/context.mjs.map +1 -0
  18. package/dist/config.d.mts +105 -0
  19. package/dist/config.d.mts.map +1 -0
  20. package/dist/config.mjs +70 -0
  21. package/dist/config.mjs.map +1 -0
  22. package/dist/file-builder.mjs +66 -0
  23. package/dist/file-builder.mjs.map +1 -0
  24. package/dist/{esm/generate-utils.js → generate-utils.mjs} +95 -27
  25. package/dist/generate-utils.mjs.map +1 -0
  26. package/dist/index.d.mts +21 -0
  27. package/dist/index.d.mts.map +1 -0
  28. package/dist/index.mjs +80 -0
  29. package/dist/index.mjs.map +1 -0
  30. package/dist/move-module-builder.mjs +350 -0
  31. package/dist/move-module-builder.mjs.map +1 -0
  32. package/dist/render-types.mjs +207 -0
  33. package/dist/render-types.mjs.map +1 -0
  34. package/dist/utils.mjs +89 -0
  35. package/dist/utils.mjs.map +1 -0
  36. package/docs/index.md +436 -0
  37. package/docs/llms-index.md +6 -0
  38. package/package.json +29 -28
  39. package/src/bin/bash-complete.ts +18 -7
  40. package/src/bin/cli.ts +3 -9
  41. package/src/cli/commands/generate/command.ts +32 -0
  42. package/src/cli/commands/generate/impl.ts +93 -5
  43. package/src/config.ts +53 -5
  44. package/src/file-builder.ts +15 -1
  45. package/src/generate-utils.ts +88 -18
  46. package/src/index.ts +89 -29
  47. package/src/move-module-builder.ts +181 -76
  48. package/src/render-types.ts +82 -29
  49. package/dist/cjs/bin/bash-complete.d.ts +0 -2
  50. package/dist/cjs/bin/bash-complete.js +0 -51
  51. package/dist/cjs/bin/bash-complete.js.map +0 -7
  52. package/dist/cjs/bin/cli.d.ts +0 -2
  53. package/dist/cjs/bin/cli.js +0 -34
  54. package/dist/cjs/bin/cli.js.map +0 -7
  55. package/dist/cjs/cli/cli.d.ts +0 -1
  56. package/dist/cjs/cli/cli.js +0 -49
  57. package/dist/cjs/cli/cli.js.map +0 -7
  58. package/dist/cjs/cli/commands/generate/command.d.ts +0 -1
  59. package/dist/cjs/cli/commands/generate/command.js +0 -80
  60. package/dist/cjs/cli/commands/generate/command.js.map +0 -7
  61. package/dist/cjs/cli/commands/generate/impl.d.ts +0 -8
  62. package/dist/cjs/cli/commands/generate/impl.js +0 -66
  63. package/dist/cjs/cli/commands/generate/impl.js.map +0 -7
  64. package/dist/cjs/cli/context.d.ts +0 -6
  65. package/dist/cjs/cli/context.js +0 -45
  66. package/dist/cjs/cli/context.js.map +0 -7
  67. package/dist/cjs/config.d.ts +0 -51
  68. package/dist/cjs/config.js +0 -75
  69. package/dist/cjs/config.js.map +0 -7
  70. package/dist/cjs/file-builder.d.ts +0 -13
  71. package/dist/cjs/file-builder.js +0 -83
  72. package/dist/cjs/file-builder.js.map +0 -7
  73. package/dist/cjs/generate-utils.d.ts +0 -1
  74. package/dist/cjs/generate-utils.js +0 -187
  75. package/dist/cjs/generate-utils.js.map +0 -7
  76. package/dist/cjs/index.d.ts +0 -8
  77. package/dist/cjs/index.js +0 -124
  78. package/dist/cjs/index.js.map +0 -7
  79. package/dist/cjs/move-module-builder.d.ts +0 -26
  80. package/dist/cjs/move-module-builder.js +0 -464
  81. package/dist/cjs/move-module-builder.js.map +0 -7
  82. package/dist/cjs/package.json +0 -5
  83. package/dist/cjs/render-types.d.ts +0 -19
  84. package/dist/cjs/render-types.js +0 -313
  85. package/dist/cjs/render-types.js.map +0 -7
  86. package/dist/cjs/summary.d.ts +0 -3
  87. package/dist/cjs/summary.js +0 -218
  88. package/dist/cjs/summary.js.map +0 -7
  89. package/dist/cjs/types/deserialized.d.ts +0 -89
  90. package/dist/cjs/types/deserialized.js +0 -17
  91. package/dist/cjs/types/deserialized.js.map +0 -7
  92. package/dist/cjs/types/summary.d.ts +0 -105
  93. package/dist/cjs/types/summary.js +0 -17
  94. package/dist/cjs/types/summary.js.map +0 -7
  95. package/dist/cjs/utils.d.ts +0 -22
  96. package/dist/cjs/utils.js +0 -164
  97. package/dist/cjs/utils.js.map +0 -7
  98. package/dist/esm/bin/bash-complete.d.ts +0 -2
  99. package/dist/esm/bin/bash-complete.js +0 -31
  100. package/dist/esm/bin/bash-complete.js.map +0 -7
  101. package/dist/esm/bin/cli.d.ts +0 -2
  102. package/dist/esm/bin/cli.js +0 -32
  103. package/dist/esm/bin/cli.js.map +0 -7
  104. package/dist/esm/cli/cli.d.ts +0 -1
  105. package/dist/esm/cli/cli.js +0 -29
  106. package/dist/esm/cli/cli.js.map +0 -7
  107. package/dist/esm/cli/commands/generate/command.d.ts +0 -1
  108. package/dist/esm/cli/commands/generate/command.js +0 -50
  109. package/dist/esm/cli/commands/generate/command.js.map +0 -7
  110. package/dist/esm/cli/commands/generate/impl.d.ts +0 -8
  111. package/dist/esm/cli/commands/generate/impl.js +0 -46
  112. package/dist/esm/cli/commands/generate/impl.js.map +0 -7
  113. package/dist/esm/cli/context.d.ts +0 -6
  114. package/dist/esm/cli/context.js +0 -15
  115. package/dist/esm/cli/context.js.map +0 -7
  116. package/dist/esm/config.d.ts +0 -51
  117. package/dist/esm/config.js +0 -45
  118. package/dist/esm/config.js.map +0 -7
  119. package/dist/esm/file-builder.d.ts +0 -13
  120. package/dist/esm/file-builder.js +0 -63
  121. package/dist/esm/file-builder.js.map +0 -7
  122. package/dist/esm/generate-utils.d.ts +0 -1
  123. package/dist/esm/generate-utils.js.map +0 -7
  124. package/dist/esm/index.d.ts +0 -8
  125. package/dist/esm/index.js +0 -104
  126. package/dist/esm/index.js.map +0 -7
  127. package/dist/esm/move-module-builder.d.ts +0 -26
  128. package/dist/esm/move-module-builder.js +0 -457
  129. package/dist/esm/move-module-builder.js.map +0 -7
  130. package/dist/esm/package.json +0 -5
  131. package/dist/esm/render-types.d.ts +0 -19
  132. package/dist/esm/render-types.js +0 -293
  133. package/dist/esm/render-types.js.map +0 -7
  134. package/dist/esm/summary.d.ts +0 -3
  135. package/dist/esm/summary.js +0 -198
  136. package/dist/esm/summary.js.map +0 -7
  137. package/dist/esm/types/deserialized.d.ts +0 -89
  138. package/dist/esm/types/deserialized.js +0 -1
  139. package/dist/esm/types/deserialized.js.map +0 -7
  140. package/dist/esm/types/summary.d.ts +0 -105
  141. package/dist/esm/types/summary.js +0 -1
  142. package/dist/esm/types/summary.js.map +0 -7
  143. package/dist/esm/utils.d.ts +0 -22
  144. package/dist/esm/utils.js +0 -134
  145. package/dist/esm/utils.js.map +0 -7
  146. package/dist/tsconfig.esm.tsbuildinfo +0 -1
  147. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-types.mjs","names":["type"],"sources":["../src/render-types.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { normalizeHaneulAddress } from '@haneullabs/haneul/utils';\n\nimport type {\n\tDatatype,\n\tDatatypeParameter,\n\tModuleSummary,\n\tType,\n\tTypeParameter,\n} from './types/summary.js';\n\nexport const MOVE_STDLIB_ADDRESS = normalizeHaneulAddress('0x1');\nexport const HANEUL_FRAMEWORK_ADDRESS = normalizeHaneulAddress('0x2');\nexport const HANEUL_SYSTEM_ADDRESS = normalizeHaneulAddress('0x3');\n\ntype TypeSignatureFormat = 'typescriptArg' | 'bcs' | 'typeTag';\ninterface RenderTypeSignatureOptions {\n\tformat: TypeSignatureFormat;\n\tsummary: ModuleSummary;\n\ttypeParameters?: TypeParameter[];\n\tonDependency?: (address: string, module: string, type: string) => string | undefined;\n\tbcsImport?: () => string;\n\tonTypeParameter?: (typeParameter: number | string) => void;\n\tresolveAddress: (address: string) => string;\n\tincludePhantomTypeParameters: boolean;\n}\n\nfunction getFilteredTypeParameterIndex(\n\toriginalIndex: number,\n\ttypeParameters: TypeParameter[] | undefined,\n\tincludePhantom: boolean,\n): number {\n\tif (includePhantom || !typeParameters) return originalIndex;\n\n\tlet filteredIndex = 0;\n\tfor (let i = 0; i < originalIndex; i++) {\n\t\tconst param = typeParameters[i] as DatatypeParameter | undefined;\n\t\tif (!param?.phantom) {\n\t\t\tfilteredIndex++;\n\t\t}\n\t}\n\treturn filteredIndex;\n}\n\nexport function renderTypeSignature(type: Type, options: RenderTypeSignatureOptions): string {\n\tlet bcs = 'bcs';\n\tif (options.bcsImport && usesBcs(type, options)) {\n\t\tbcs = options.bcsImport();\n\t}\n\n\tswitch (type) {\n\t\tcase 'address':\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\treturn 'string';\n\t\t\t\tcase 'typeTag':\n\t\t\t\t\treturn `address`;\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${bcs}.Address`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\tcase 'bool':\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\treturn 'boolean';\n\t\t\t\tcase 'typeTag':\n\t\t\t\t\treturn `bool`;\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${bcs}.bool()`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\tcase 'u8':\n\t\tcase 'u16':\n\t\tcase 'u32':\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\treturn 'number';\n\t\t\t\tcase 'typeTag':\n\t\t\t\t\treturn type.toLowerCase();\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${bcs}.${type.toLowerCase()}()`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\tcase 'u64':\n\t\tcase 'u128':\n\t\tcase 'u256':\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\treturn `number | bigint`;\n\t\t\t\tcase 'typeTag':\n\t\t\t\t\treturn type.toLowerCase();\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${bcs}.${type.toLowerCase()}()`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\tcase 'signer':\n\t\t\tthrow new Error('Signer is not supported');\n\t\tcase '_':\n\t\t\tthrow new Error('Macro placeholder is not supported');\n\t}\n\n\tif ('Datatype' in type) {\n\t\treturn renderDataType(type.Datatype, options);\n\t}\n\n\tif ('Reference' in type) {\n\t\treturn renderTypeSignature(type.Reference[1], options);\n\t}\n\n\tif ('vector' in type) {\n\t\tswitch (options.format) {\n\t\t\tcase 'typescriptArg':\n\t\t\t\treturn `${renderTypeSignature(type.vector, options)}[]`;\n\t\t\tcase 'typeTag':\n\t\t\t\treturn `vector<${renderTypeSignature(type.vector, options)}>`;\n\t\t\tcase 'bcs':\n\t\t\t\treturn `${bcs}.vector(${renderTypeSignature(type.vector, options)})`;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t}\n\t}\n\n\tif ('TypeParameter' in type) {\n\t\toptions.onTypeParameter?.(type.TypeParameter);\n\t\tconst originalIndex = type.TypeParameter;\n\t\tconst filteredIndex = getFilteredTypeParameterIndex(\n\t\t\toriginalIndex,\n\t\t\toptions.typeParameters,\n\t\t\toptions.includePhantomTypeParameters,\n\t\t);\n\t\tswitch (options.format) {\n\t\t\tcase 'typescriptArg':\n\t\t\t\treturn options.typeParameters?.[originalIndex]?.name ?? `T${originalIndex}`;\n\t\t\tcase 'typeTag':\n\t\t\t\treturn `\\${options.typeArguments[${originalIndex}]}`;\n\t\t\tcase 'bcs':\n\t\t\t\treturn `typeParameters[${filteredIndex}]`;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t}\n\t}\n\n\tif ('NamedTypeParameter' in type) {\n\t\toptions.onTypeParameter?.(type.NamedTypeParameter);\n\t\tconst originalIndex =\n\t\t\toptions.typeParameters?.findIndex((p) => p.name === type.NamedTypeParameter) ?? -1;\n\n\t\tif (originalIndex === -1) {\n\t\t\tthrow new Error(`Named type parameter ${type.NamedTypeParameter} not found`);\n\t\t}\n\n\t\tconst filteredIndex = getFilteredTypeParameterIndex(\n\t\t\toriginalIndex,\n\t\t\toptions.typeParameters,\n\t\t\toptions.includePhantomTypeParameters,\n\t\t);\n\n\t\tswitch (options.format) {\n\t\t\tcase 'typescriptArg':\n\t\t\t\treturn type.NamedTypeParameter;\n\t\t\tcase 'typeTag':\n\t\t\t\treturn `\\${options.typeArguments[${originalIndex}]}`;\n\t\t\tcase 'bcs':\n\t\t\t\treturn `typeParameters[${filteredIndex}]`;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t}\n\t}\n\n\tthrow new Error(`Unknown type signature: ${JSON.stringify(type, null, 2)}`);\n}\n\nexport function usesBcs(type: Type, options: RenderTypeSignatureOptions): boolean {\n\tif (typeof type === 'string') {\n\t\treturn true;\n\t}\n\n\tif ('Reference' in type) {\n\t\treturn usesBcs(type.Reference[1], options);\n\t}\n\n\tif ('Datatype' in type) {\n\t\treturn isPureDataType(type.Datatype, options);\n\t}\n\n\tif ('vector' in type) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nexport function isPureSignature(type: Type, options: RenderTypeSignatureOptions): boolean {\n\tif (typeof type === 'string') {\n\t\treturn true;\n\t}\n\n\tif ('Reference' in type) {\n\t\treturn isPureSignature(type.Reference[1], options);\n\t}\n\n\tif ('Datatype' in type) {\n\t\treturn isPureDataType(type.Datatype, options);\n\t}\n\n\tif ('vector' in type) {\n\t\treturn isPureSignature(type.vector, options);\n\t}\n\n\tif ('TypeParameter' in type) {\n\t\treturn false;\n\t}\n\n\tif ('NamedTypeParameter' in type) {\n\t\treturn false;\n\t}\n\n\tthrow new Error(`Unknown type signature: ${JSON.stringify(type, null, 2)}`);\n}\n\nfunction isPureDataType(type: Datatype, options: RenderTypeSignatureOptions) {\n\tconst address = options.resolveAddress(type.module.address);\n\n\tif (address === MOVE_STDLIB_ADDRESS) {\n\t\tif ((type.module.name === 'ascii' || type.module.name === 'string') && type.name === 'String') {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (type.module.name === 'option' && type.name === 'Option') {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (address === HANEUL_FRAMEWORK_ADDRESS) {\n\t\tif (type.module.name === 'object' && (type.name === 'ID' || type.name === 'UID')) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nfunction renderDataType(type: Datatype, options: RenderTypeSignatureOptions): string {\n\tconst address = options.resolveAddress(type.module.address);\n\n\tif (options.format === 'typeTag') {\n\t\tif (address === HANEUL_FRAMEWORK_ADDRESS) {\n\t\t\tif (type.module.name === 'clock' && type.name === 'Clock') return '0x2::clock::Clock';\n\t\t\tif (type.module.name === 'random' && type.name === 'Random') return '0x2::random::Random';\n\t\t\tif (type.module.name === 'deny_list' && type.name === 'DenyList')\n\t\t\t\treturn '0x2::deny_list::DenyList';\n\t\t\tif (type.module.name === 'object' && (type.name === 'ID' || type.name === 'UID'))\n\t\t\t\treturn '0x2::object::ID';\n\t\t}\n\t\tif (address === HANEUL_SYSTEM_ADDRESS) {\n\t\t\tif (type.module.name === 'haneul_system' && type.name === 'HaneulSystemState')\n\t\t\t\treturn '0x3::haneul_system::HaneulSystemState';\n\t\t}\n\n\t\tif (address === MOVE_STDLIB_ADDRESS) {\n\t\t\tif (\n\t\t\t\t(type.module.name === 'ascii' || type.module.name === 'string') &&\n\t\t\t\ttype.name === 'String'\n\t\t\t) {\n\t\t\t\treturn '0x1::string::String';\n\t\t\t}\n\t\t\tif (type.module.name === 'option' && type.name === 'Option') {\n\t\t\t\tconst innerType = renderTypeSignature(type.type_arguments[0].argument, options);\n\t\t\t\treturn `0x1::option::Option<${innerType}>`;\n\t\t\t}\n\t\t}\n\n\t\treturn 'null';\n\t}\n\n\tif (address === MOVE_STDLIB_ADDRESS) {\n\t\tif ((type.module.name === 'ascii' || type.module.name === 'string') && type.name === 'String') {\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\treturn 'string';\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${options.bcsImport?.() ?? 'bcs'}.string()`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\t}\n\n\t\tif (type.module.name === 'option' && type.name === 'Option') {\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\tif (isPureDataType(type, options)) {\n\t\t\t\t\t\treturn `${renderTypeSignature(type.type_arguments[0].argument, options)} | null`;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${options.bcsImport?.() ?? 'bcs'}.option(${renderTypeSignature(type.type_arguments[0].argument, options)})`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (address === HANEUL_FRAMEWORK_ADDRESS) {\n\t\tif (type.module.name === 'object' && (type.name === 'ID' || type.name === 'UID')) {\n\t\t\tswitch (options.format) {\n\t\t\t\tcase 'typescriptArg':\n\t\t\t\t\treturn 'string';\n\t\t\t\tcase 'bcs':\n\t\t\t\t\treturn `${options.bcsImport?.() ?? 'bcs'}.Address`;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst isCurrentModule =\n\t\taddress === options.resolveAddress(options.summary.id.address) &&\n\t\ttype.module.name === options.summary.id.name;\n\n\tconst importName = options.onDependency?.(type.module.address, type.module.name, type.name);\n\n\tconst typeNameRef = isCurrentModule\n\t\t? type.name\n\t\t: `${importName ?? getSafeName(type.module.name)}.${getSafeName(type.name)}`;\n\n\tconst filteredTypeArguments = type.type_arguments.filter((arg) => !arg.phantom);\n\n\tswitch (options.format) {\n\t\tcase 'typescriptArg':\n\t\t\treturn 'string';\n\t\tcase 'bcs':\n\t\t\tif (filteredTypeArguments.length === 0) {\n\t\t\t\treturn typeNameRef;\n\t\t\t}\n\n\t\t\treturn `${typeNameRef}(\n ${filteredTypeArguments.map((type) => renderTypeSignature(type.argument, options)).join(', ')})`;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown format: ${options.format}`);\n\t}\n}\n\nconst JS_RESERVED_NAMES = [\n\t'new',\n\t'delete',\n\t'class',\n\t'function',\n\t'import',\n\t'export',\n\t'return',\n\t'this',\n\t'super',\n\t'arguments',\n\t'eval',\n\t'void',\n\t'typeof',\n\t'instanceof',\n\t'delete',\n\t'in',\n\t'from',\n\t'of',\n\t'as',\n\t'async',\n\t'await',\n\t'break',\n\t'case',\n\t'catch',\n\t'continue',\n\t'debugger',\n\t'default',\n\t'do',\n\t'else',\n\t'finally',\n\t'for',\n\t'function',\n\t'if',\n\t'import',\n\t'in',\n\t'instanceof',\n\t'new',\n\t'return',\n\t'switch',\n\t'throw',\n\t'try',\n\t'typeof',\n\t'var',\n\t'void',\n\t'while',\n\t'with',\n\t'yield',\n\t'package',\n];\n\nexport function getSafeName(name: string) {\n\treturn JS_RESERVED_NAMES.includes(name) ? `_${name}` : name;\n}\n"],"mappings":"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"}
package/dist/utils.mjs ADDED
@@ -0,0 +1,89 @@
1
+ import { HANEUL_FRAMEWORK_ADDRESS, HANEUL_SYSTEM_ADDRESS } from "./render-types.mjs";
2
+ import { format } from "prettier";
3
+ import ts from "typescript";
4
+
5
+ //#region src/utils.ts
6
+ function printNodes(...nodes) {
7
+ const printer = ts.createPrinter({ removeComments: false });
8
+ return nodes.map((node) => printer.printNode(ts.EmitHint.Unspecified, node, node.getSourceFile())).join("\n");
9
+ }
10
+ function parseTS(strings, ...values) {
11
+ const lines = strings.reduce((acc, str, i) => {
12
+ if (typeof values[i] === "object") {
13
+ if (Array.isArray(values[i])) return `${acc}${str}${printNodes(...values[i])}`;
14
+ return `${acc}${str}${printNodes(values[i])}`;
15
+ }
16
+ return `${acc}${str}${values[i] ?? ""}`;
17
+ }, "").replace(/^\s/m, "").split("\n");
18
+ const indent = lines[0].match(/^\s*/)?.[0] ?? "";
19
+ const unIndented = lines.map((line) => line.replace(indent, "")).join("\n");
20
+ return [...ts.createSourceFile("file.ts", unIndented, ts.ScriptTarget.Latest, true).statements.values()];
21
+ }
22
+ async function mapToObject({ items, mapper, getComment }) {
23
+ const fieldProps = await Promise.all((await Promise.all([...items].map(async (item) => {
24
+ const mapped = await mapper(item);
25
+ if (!mapped) return null;
26
+ const [key, value] = mapped;
27
+ return [
28
+ item,
29
+ key,
30
+ value
31
+ ];
32
+ }))).filter((value) => value !== null).map(([item, key, value]) => {
33
+ const [node] = parseTS`({${key}: ${value}})`;
34
+ if (!ts.isExpressionStatement(node)) throw new Error("Expected Expression statement");
35
+ if (!ts.isParenthesizedExpression(node.expression)) throw new Error("Expected Parenthesized Expression");
36
+ if (!ts.isObjectLiteralExpression(node.expression.expression)) throw new Error("Expected Object Literal Expression");
37
+ const comment = getComment?.(item);
38
+ return withComment({ comment }, node.expression.expression.properties[0]);
39
+ }));
40
+ return ts.factory.createObjectLiteralExpression(fieldProps, true);
41
+ }
42
+ async function withComment(options, nodes) {
43
+ const comment = options.comment ?? options.doc;
44
+ if (comment) {
45
+ const firstNode = Array.isArray(nodes) ? nodes[0] : nodes;
46
+ ts.addSyntheticLeadingComment(firstNode, ts.SyntaxKind.MultiLineCommentTrivia, await formatComment(comment), true);
47
+ }
48
+ return nodes;
49
+ }
50
+ async function formatComment(text) {
51
+ const lines = (await format(text, {
52
+ printWidth: 80,
53
+ semi: true,
54
+ singleQuote: true,
55
+ tabWidth: 2,
56
+ trailingComma: "all",
57
+ useTabs: true,
58
+ proseWrap: "always",
59
+ parser: "markdown"
60
+ })).trim().replaceAll("*/", "*\\/").split("\n");
61
+ if (lines.length === 1) return `* ${lines[0]} `;
62
+ return `*\n${lines.map((line) => ` * ${line}`).join("\n")}\n `;
63
+ }
64
+ function camelCase(str) {
65
+ return str.replaceAll(/(?:_)([a-z])/g, (_, letter) => letter.toUpperCase());
66
+ }
67
+ function capitalize(str) {
68
+ return str.charAt(0).toUpperCase() + str.slice(1);
69
+ }
70
+ function isWellKnownObjectParameter(type, resolveAddress) {
71
+ if (typeof type === "string") return false;
72
+ if ("Reference" in type) return isWellKnownObjectParameter(type.Reference[1], resolveAddress);
73
+ if (!("Datatype" in type)) return false;
74
+ const { Datatype } = type;
75
+ const address = resolveAddress(Datatype.module.address);
76
+ if (address === HANEUL_FRAMEWORK_ADDRESS) {
77
+ if (Datatype.module.name === "deny_list") return Datatype.name === "DenyList";
78
+ if (Datatype.module.name === "random") return Datatype.name === "Random";
79
+ if (Datatype.module.name === "clock") return Datatype.name === "Clock";
80
+ }
81
+ if (address === HANEUL_SYSTEM_ADDRESS) {
82
+ if (Datatype.module.name === "haneul_system") return Datatype.name === "HaneulSystemState";
83
+ }
84
+ return false;
85
+ }
86
+
87
+ //#endregion
88
+ export { camelCase, capitalize, formatComment, isWellKnownObjectParameter, mapToObject, parseTS, printNodes, withComment };
89
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { format } from 'prettier';\nimport ts from 'typescript';\nimport type { Type } from './types/summary.js';\nimport { HANEUL_FRAMEWORK_ADDRESS, HANEUL_SYSTEM_ADDRESS } from './render-types.js';\n\nexport function printNodes(...nodes: ts.Node[]) {\n\tconst printer = ts.createPrinter({\n\t\tremoveComments: false,\n\t});\n\n\treturn nodes\n\t\t.map((node) => printer.printNode(ts.EmitHint.Unspecified, node, node.getSourceFile()))\n\t\t.join('\\n');\n}\n\ntype TSTemplateValue = string | number | boolean | ts.Statement[] | ts.Expression;\n\nexport function parseTS(strings: TemplateStringsArray, ...values: TSTemplateValue[]) {\n\tconst source = strings.reduce((acc, str, i) => {\n\t\tif (typeof values[i] === 'object') {\n\t\t\tif (Array.isArray(values[i])) {\n\t\t\t\treturn `${acc}${str}${printNodes(...values[i])}`;\n\t\t\t}\n\n\t\t\treturn `${acc}${str}${printNodes(values[i])}`;\n\t\t}\n\n\t\treturn `${acc}${str}${values[i] ?? ''}`;\n\t}, '');\n\n\tconst lines = source.replace(/^\\s/m, '').split('\\n');\n\tconst firstLine = lines[0];\n\tconst indent = firstLine.match(/^\\s*/)?.[0] ?? '';\n\tconst unIndented = lines.map((line) => line.replace(indent, '')).join('\\n');\n\n\tconst sourceFile = ts.createSourceFile('file.ts', unIndented, ts.ScriptTarget.Latest, true);\n\treturn [...sourceFile.statements.values()];\n}\n\nexport async function mapToObject<T>({\n\titems,\n\tmapper,\n\tgetComment,\n}: {\n\titems: Iterable<T>;\n\tmapper: (item: T) => Promise<null | [string, TSTemplateValue]> | null | [string, TSTemplateValue];\n\tgetComment?: (item: T) => string | null | undefined;\n}) {\n\tconst fieldProps = await Promise.all(\n\t\t(\n\t\t\tawait Promise.all(\n\t\t\t\t[...items].map(async (item) => {\n\t\t\t\t\tconst mapped = await mapper(item);\n\t\t\t\t\tif (!mapped) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [key, value] = mapped;\n\t\t\t\t\treturn [item, key, value] as const;\n\t\t\t\t}),\n\t\t\t)\n\t\t)\n\t\t\t.filter((value) => value !== null)\n\t\t\t.map(([item, key, value]) => {\n\t\t\t\tconst [node] = parseTS /* ts */ `({${key}: ${value}})`;\n\n\t\t\t\tif (!ts.isExpressionStatement(node)) {\n\t\t\t\t\tthrow new Error('Expected Expression statement');\n\t\t\t\t}\n\n\t\t\t\tif (!ts.isParenthesizedExpression(node.expression)) {\n\t\t\t\t\tthrow new Error('Expected Parenthesized Expression');\n\t\t\t\t}\n\n\t\t\t\tif (!ts.isObjectLiteralExpression(node.expression.expression)) {\n\t\t\t\t\tthrow new Error('Expected Object Literal Expression');\n\t\t\t\t}\n\n\t\t\t\tconst comment = getComment?.(item);\n\t\t\t\treturn withComment({ comment }, node.expression.expression.properties[0]);\n\t\t\t}),\n\t);\n\n\treturn ts.factory.createObjectLiteralExpression(fieldProps, true);\n}\n\nexport async function withComment<T extends ts.Node | ts.Node[]>(\n\toptions:\n\t\t| { comment?: string | null; doc?: never }\n\t\t| { doc?: string | null | undefined; comment?: never },\n\tnodes: T,\n): Promise<T> {\n\tconst comment = options.comment ?? options.doc;\n\n\tif (comment) {\n\t\tconst firstNode = Array.isArray(nodes) ? nodes[0] : (nodes as ts.Node);\n\t\tts.addSyntheticLeadingComment(\n\t\t\tfirstNode,\n\t\t\tts.SyntaxKind.MultiLineCommentTrivia,\n\t\t\tawait formatComment(comment),\n\t\t\ttrue,\n\t\t);\n\t}\n\n\treturn nodes;\n}\n\nexport async function formatComment(text: string) {\n\tconst lines = (\n\t\tawait format(text, {\n\t\t\tprintWidth: 80,\n\t\t\tsemi: true,\n\t\t\tsingleQuote: true,\n\t\t\ttabWidth: 2,\n\t\t\ttrailingComma: 'all',\n\t\t\tuseTabs: true,\n\t\t\tproseWrap: 'always',\n\t\t\tparser: 'markdown',\n\t\t})\n\t)\n\t\t.trim()\n\t\t.replaceAll('*/', '*\\\\/')\n\t\t.split('\\n');\n\n\tif (lines.length === 1) return `* ${lines[0]} `;\n\n\treturn `*\\n${lines.map((line) => ` * ${line}`).join('\\n')}\\n `;\n}\n\nexport function camelCase(str: string) {\n\treturn str.replaceAll(/(?:_)([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\nexport function capitalize(str: string) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nexport function isWellKnownObjectParameter(\n\ttype: Type,\n\tresolveAddress: (address: string) => string,\n) {\n\tif (typeof type === 'string') {\n\t\treturn false;\n\t}\n\n\tif ('Reference' in type) {\n\t\treturn isWellKnownObjectParameter(type.Reference[1], resolveAddress);\n\t}\n\n\tif (!('Datatype' in type)) {\n\t\treturn false;\n\t}\n\n\tconst { Datatype } = type;\n\n\tconst address = resolveAddress(Datatype.module.address);\n\tif (address === HANEUL_FRAMEWORK_ADDRESS) {\n\t\tif (Datatype.module.name === 'deny_list') {\n\t\t\treturn Datatype.name === 'DenyList';\n\t\t}\n\n\t\tif (Datatype.module.name === 'random') {\n\t\t\treturn Datatype.name === 'Random';\n\t\t}\n\n\t\tif (Datatype.module.name === 'clock') {\n\t\t\treturn Datatype.name === 'Clock';\n\t\t}\n\t}\n\n\tif (address === HANEUL_SYSTEM_ADDRESS) {\n\t\tif (Datatype.module.name === 'haneul_system') {\n\t\t\treturn Datatype.name === 'HaneulSystemState';\n\t\t}\n\t}\n\n\treturn false;\n}\n"],"mappings":";;;;;AAOA,SAAgB,WAAW,GAAG,OAAkB;CAC/C,MAAM,UAAU,GAAG,cAAc,EAChC,gBAAgB,OAChB,CAAC;AAEF,QAAO,MACL,KAAK,SAAS,QAAQ,UAAU,GAAG,SAAS,aAAa,MAAM,KAAK,eAAe,CAAC,CAAC,CACrF,KAAK,KAAK;;AAKb,SAAgB,QAAQ,SAA+B,GAAG,QAA2B;CAapF,MAAM,QAZS,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAC9C,MAAI,OAAO,OAAO,OAAO,UAAU;AAClC,OAAI,MAAM,QAAQ,OAAO,GAAG,CAC3B,QAAO,GAAG,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG;AAG/C,UAAO,GAAG,MAAM,MAAM,WAAW,OAAO,GAAG;;AAG5C,SAAO,GAAG,MAAM,MAAM,OAAO,MAAM;IACjC,GAAG,CAEe,QAAQ,QAAQ,GAAG,CAAC,MAAM,KAAK;CAEpD,MAAM,SADY,MAAM,GACC,MAAM,OAAO,GAAG,MAAM;CAC/C,MAAM,aAAa,MAAM,KAAK,SAAS,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK,KAAK;AAG3E,QAAO,CAAC,GADW,GAAG,iBAAiB,WAAW,YAAY,GAAG,aAAa,QAAQ,KAAK,CACrE,WAAW,QAAQ,CAAC;;AAG3C,eAAsB,YAAe,EACpC,OACA,QACA,cAKE;CACF,MAAM,aAAa,MAAM,QAAQ,KAE/B,MAAM,QAAQ,IACb,CAAC,GAAG,MAAM,CAAC,IAAI,OAAO,SAAS;EAC9B,MAAM,SAAS,MAAM,OAAO,KAAK;AACjC,MAAI,CAAC,OACJ,QAAO;EAGR,MAAM,CAAC,KAAK,SAAS;AACrB,SAAO;GAAC;GAAM;GAAK;GAAM;GACxB,CACF,EAEA,QAAQ,UAAU,UAAU,KAAK,CACjC,KAAK,CAAC,MAAM,KAAK,WAAW;EAC5B,MAAM,CAAC,QAAQ,OAAiB,KAAK,IAAI,IAAI,MAAM;AAEnD,MAAI,CAAC,GAAG,sBAAsB,KAAK,CAClC,OAAM,IAAI,MAAM,gCAAgC;AAGjD,MAAI,CAAC,GAAG,0BAA0B,KAAK,WAAW,CACjD,OAAM,IAAI,MAAM,oCAAoC;AAGrD,MAAI,CAAC,GAAG,0BAA0B,KAAK,WAAW,WAAW,CAC5D,OAAM,IAAI,MAAM,qCAAqC;EAGtD,MAAM,UAAU,aAAa,KAAK;AAClC,SAAO,YAAY,EAAE,SAAS,EAAE,KAAK,WAAW,WAAW,WAAW,GAAG;GACxE,CACH;AAED,QAAO,GAAG,QAAQ,8BAA8B,YAAY,KAAK;;AAGlE,eAAsB,YACrB,SAGA,OACa;CACb,MAAM,UAAU,QAAQ,WAAW,QAAQ;AAE3C,KAAI,SAAS;EACZ,MAAM,YAAY,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAM;AACrD,KAAG,2BACF,WACA,GAAG,WAAW,wBACd,MAAM,cAAc,QAAQ,EAC5B,KACA;;AAGF,QAAO;;AAGR,eAAsB,cAAc,MAAc;CACjD,MAAM,SACL,MAAM,OAAO,MAAM;EAClB,YAAY;EACZ,MAAM;EACN,aAAa;EACb,UAAU;EACV,eAAe;EACf,SAAS;EACT,WAAW;EACX,QAAQ;EACR,CAAC,EAED,MAAM,CACN,WAAW,MAAM,OAAO,CACxB,MAAM,KAAK;AAEb,KAAI,MAAM,WAAW,EAAG,QAAO,KAAK,MAAM,GAAG;AAE7C,QAAO,MAAM,MAAM,KAAK,SAAS,MAAM,OAAO,CAAC,KAAK,KAAK,CAAC;;AAG3D,SAAgB,UAAU,KAAa;AACtC,QAAO,IAAI,WAAW,kBAAkB,GAAG,WAAW,OAAO,aAAa,CAAC;;AAG5E,SAAgB,WAAW,KAAa;AACvC,QAAO,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE;;AAGlD,SAAgB,2BACf,MACA,gBACC;AACD,KAAI,OAAO,SAAS,SACnB,QAAO;AAGR,KAAI,eAAe,KAClB,QAAO,2BAA2B,KAAK,UAAU,IAAI,eAAe;AAGrE,KAAI,EAAE,cAAc,MACnB,QAAO;CAGR,MAAM,EAAE,aAAa;CAErB,MAAM,UAAU,eAAe,SAAS,OAAO,QAAQ;AACvD,KAAI,YAAY,0BAA0B;AACzC,MAAI,SAAS,OAAO,SAAS,YAC5B,QAAO,SAAS,SAAS;AAG1B,MAAI,SAAS,OAAO,SAAS,SAC5B,QAAO,SAAS,SAAS;AAG1B,MAAI,SAAS,OAAO,SAAS,QAC5B,QAAO,SAAS,SAAS;;AAI3B,KAAI,YAAY,uBACf;MAAI,SAAS,OAAO,SAAS,gBAC5B,QAAO,SAAS,SAAS;;AAI3B,QAAO"}
package/docs/index.md ADDED
@@ -0,0 +1,436 @@
1
+ # Haneul TypeScript Codegen
2
+
3
+ > Generate type-safe TypeScript bindings from on-chain Haneul Move packages
4
+
5
+ The `@haneullabs/codegen` package automatically generates type-safe TypeScript code from your Move
6
+ packages, enabling seamless interaction with your smart contracts from TypeScript applications.
7
+
8
+ > **Warning:** This package is currently in development and may have breaking changes.
9
+
10
+ ## Features
11
+
12
+ - **Type-safe Move calls**: Generate TypeScript functions with full type safety for calling your
13
+ Move functions
14
+ - **BCS type definitions**: Automatic BCS struct definitions for parsing on-chain data
15
+ - **Auto-completion**: IDE support with intelligent code completion for Move function arguments
16
+ - **Package resolution**: Support for both MVR-registered packages and local packages
17
+
18
+ ## Installation
19
+
20
+ Install the codegen package as a dev dependency:
21
+
22
+ ```sh npm2yarn
23
+ npm install -D @haneullabs/codegen
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### 1. Create a configuration file
29
+
30
+ Create a `haneul-codegen.config.ts` file in your project root:
31
+
32
+ ```typescript
33
+ const config: HaneulCodegenConfig = {
34
+ output: './src/contracts',
35
+ packages: [
36
+ {
37
+ package: '@local-pkg/counter',
38
+ path: './move/counter',
39
+ },
40
+ ],
41
+ };
42
+ ```
43
+
44
+ ### 2. Generate TypeScript code
45
+
46
+ Add a script to your `package.json`:
47
+
48
+ ```json
49
+ {
50
+ "scripts": {
51
+ "codegen": "haneul-ts-codegen generate"
52
+ }
53
+ }
54
+ ```
55
+
56
+ Then run:
57
+
58
+ ```bash
59
+ pnpm codegen
60
+ ```
61
+
62
+ This generates TypeScript code in your configured output directory (e.g., `./src/contracts`).
63
+
64
+ ## Configuration Options
65
+
66
+ The `HaneulCodegenConfig` type supports the following options:
67
+
68
+ | Option | Type | Default | Description |
69
+ | ------------------------------ | ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
+ | `output` | `string` | — | The directory where generated code will be written |
71
+ | `packages` | `PackageConfig[]` | — | Array of Move packages to generate code for |
72
+ | `prune` | `boolean` | `true` | When enabled, only generates code for the main package and omits dependency modules (dependency types referenced by included types are still generated under `deps/`) |
73
+ | `generateSummaries` | `boolean` | `true` | Automatically run `haneul move summary` before generating code. Creates a `package_summaries` directory in your Move package which can be added to `.gitignore` |
74
+ | `generate` | `GenerateOptions` | — | Default [generate options](#the-generate-option) (types, functions) for all packages |
75
+ | `importExtension` | `'.js' \| '.ts' \| ''` | `'.js'` | File extension used in generated import statements |
76
+ | `includePhantomTypeParameters` | `boolean` | `false` | Include [phantom type parameters](#phantom-types) as function arguments in generated BCS types |
77
+
78
+ ### Package Configuration
79
+
80
+ Each entry in the `packages` array configures a Move package to generate code from. Packages can be
81
+ local (from source) or on-chain (fetched from a network).
82
+
83
+ #### Local Packages
84
+
85
+ | Option | Type | Required | Description |
86
+ | ------------- | ------------------------ | -------- | -------------------------------------------------- |
87
+ | `package` | `string` | yes | Package identifier (e.g., `@local-pkg/my-package`) |
88
+ | `path` | `string` | yes | Path to the Move package directory |
89
+ | `packageName` | `string` | no | Custom name for generated code directory |
90
+ | `generate` | `PackageGenerateOptions` | no | Control what gets generated from this package |
91
+
92
+ ```typescript
93
+ {
94
+ package: '@local-pkg/my-package',
95
+ path: './move/my-package',
96
+ }
97
+ ```
98
+
99
+ #### On-Chain Packages
100
+
101
+ For packages already deployed on-chain, generate code directly from a package ID or MVR name without
102
+ needing local source code:
103
+
104
+ | Option | Type | Required | Description |
105
+ | ------------- | ------------------------ | -------- | --------------------------------------------- |
106
+ | `package` | `string` | yes | Package ID or MVR name |
107
+ | `packageName` | `string` | yes | Name for the generated code directory |
108
+ | `network` | `'mainnet' \| 'testnet'` | yes | Network to fetch the package from |
109
+ | `generate` | `PackageGenerateOptions` | no | Control what gets generated from this package |
110
+
111
+ ```typescript
112
+ {
113
+ package: '0xabf837e98c26087cba0883c0a7a28326b1fa3c5e1e2c5abdb486f9e8f594c837',
114
+ packageName: 'pyth',
115
+ network: 'testnet',
116
+ }
117
+ ```
118
+
119
+ ## The `generate` option
120
+
121
+ The `generate` option controls what code is produced. It can be set at the global level (as a
122
+ default for all packages), at the per-package level, and at the per-module level. More specific
123
+ settings override less specific ones.
124
+
125
+ When no `generate` option is set, everything is generated (all types and functions). Package-level
126
+ `types` and `functions` also default to `true`. In the record form of `modules`, per-module `types`
127
+ and `functions` default to `false` — you opt in to exactly what you need from each module. Use
128
+ `true` as a shorthand to include everything from a module with package-level defaults.
129
+
130
+ At the **global** and **package** levels, `types` and `functions` only accept boolean values (or an
131
+ object for `functions`). Name-based filtering with `string[]` is only available at the **module**
132
+ level inside the record form of `modules`, where the filter applies unambiguously to a single
133
+ module.
134
+
135
+ ```typescript
136
+ // Global or package level
137
+ generate: {
138
+ types: true | false,
139
+ functions: true | false | { private: boolean | 'entry' },
140
+ modules: string[] | Record<string, true | { types?, functions? }>, // package-level only
141
+ }
142
+
143
+ // Module level (inside the record form of modules)
144
+ modules: {
145
+ my_module: true, // shorthand for "include everything"
146
+ other_module: {
147
+ types: true | false | string[],
148
+ functions: true | false | string[] | { private: boolean | 'entry' },
149
+ }
150
+ }
151
+ ```
152
+
153
+ ### Types
154
+
155
+ Controls which BCS type definitions (structs and enums) are generated:
156
+
157
+ - `true` — generate all types
158
+ - `false` — skip type generation
159
+ - `string[]` — generate only the listed types by name _(module level only)_
160
+
161
+ ### Functions
162
+
163
+ Controls which Move function wrappers are generated:
164
+
165
+ - `true` — generate all public functions and private entry functions
166
+ - `false` — skip function generation
167
+ - `string[]` — generate only the listed functions by name; includes private functions _(module level
168
+ only)_
169
+ - `{ private: 'entry' }` — generate public functions plus private entry functions
170
+ - `{ private: true }` — generate all functions including private
171
+ - `{ private: false }` — only generate public functions
172
+
173
+ ### Modules
174
+
175
+ Controls which modules from the package are included. Only available at the package level, not at
176
+ the global level.
177
+
178
+ - Not set (default) — include all modules
179
+ - `string[]` — only include the listed modules
180
+ - `Record<string, true | { types?, functions? }>` — only include the listed modules, with per-module
181
+ overrides for `types` and `functions`. Use `true` as a shorthand to include everything from a
182
+ module with package-level defaults
183
+
184
+ ### Examples
185
+
186
+ Only generate code from specific modules of the Haneul framework:
187
+
188
+ ```typescript
189
+ {
190
+ package: '0x0000000000000000000000000000000000000000000000000000000000000002',
191
+ packageName: '0x2',
192
+ network: 'testnet',
193
+ generate: {
194
+ modules: ['kiosk', 'kiosk_extension', 'transfer_policy'],
195
+ },
196
+ }
197
+ ```
198
+
199
+ Only generate a single type from a dependency (functions are omitted automatically since `generate`
200
+ is configured and `functions` is not specified):
201
+
202
+ ```typescript
203
+ {
204
+ package: '0xabf837e98c26087cba0883c0a7a28326b1fa3c5e1e2c5abdb486f9e8f594c837',
205
+ packageName: 'pyth',
206
+ network: 'testnet',
207
+ generate: {
208
+ modules: {
209
+ state: { types: ['State'] },
210
+ },
211
+ },
212
+ }
213
+ ```
214
+
215
+ Generate specific types and functions from individual modules:
216
+
217
+ ```typescript
218
+ {
219
+ package: '@local-pkg/my-package',
220
+ path: './move/my-package',
221
+ generate: {
222
+ modules: {
223
+ token: {
224
+ types: ['Token', 'TokenMetadata'],
225
+ functions: ['mint', 'burn', 'transfer'],
226
+ },
227
+ admin: {
228
+ types: true,
229
+ functions: ['initialize'],
230
+ },
231
+ },
232
+ },
233
+ }
234
+ ```
235
+
236
+ Generate all types but include all private functions for a local package:
237
+
238
+ ```typescript
239
+ {
240
+ package: '@local-pkg/my-package',
241
+ path: './move/my-package',
242
+ generate: {
243
+ functions: { private: true },
244
+ },
245
+ }
246
+ ```
247
+
248
+ ### Dependency pruning
249
+
250
+ The global `prune` option (default: `true`) controls whether dependency packages are included in the
251
+ output. Even when pruning is enabled, dependency types referenced by your included types are still
252
+ generated under `deps/`:
253
+
254
+ ```
255
+ src/contracts/
256
+ ├── mypackage/
257
+ │ ├── module_a.ts
258
+ │ ├── module_b.ts
259
+ │ └── deps/
260
+ │ └── 0x2/
261
+ │ └── balance.ts # Auto-included dependency type
262
+ └── utils/
263
+ └── index.ts # Shared utilities (always generated)
264
+ ```
265
+
266
+ Set `prune: false` to generate all dependency modules with their full types and functions.
267
+
268
+ ## Phantom Types
269
+
270
+ In Move, phantom type parameters are type parameters that only appear at the type level and don't
271
+ affect the runtime data layout of a struct. For example, `Balance<T>` has a phantom type parameter
272
+ `T` that indicates the coin type, but the actual serialized data only contains a `u64` value:
273
+
274
+ ```move
275
+ public struct Balance<phantom T> has store {
276
+ value: u64,
277
+ }
278
+ ```
279
+
280
+ ### Default Behavior
281
+
282
+ By default, codegen excludes phantom type parameters from the generated BCS type functions since
283
+ they don't affect serialization. The generated type is a constant rather than a function:
284
+
285
+ ```typescript
286
+
287
+ name: `${$moduleName}::Balance<phantom T>`,
288
+ fields: {
289
+ value: bcs.u64(),
290
+ },
291
+ });
292
+ ```
293
+
294
+ This works correctly for parsing on-chain data because phantom types don't change the binary layout.
295
+
296
+ > **Note:** With the default behavior, phantom parameters appear as literals in the type name (e.g.,
297
+ > `Balance<phantom T>`). These names are useful for debugging but are not valid on-chain type tags.
298
+ > If you need valid type names with resolved phantom parameters, enable
299
+ > `includePhantomTypeParameters`.
300
+
301
+ ### Including Phantom Type Parameters
302
+
303
+ If you need the phantom type parameters as function arguments (for example, to preserve type
304
+ information for other tooling), enable `includePhantomTypeParameters`:
305
+
306
+ ```typescript
307
+ const config: HaneulCodegenConfig = {
308
+ output: './src/contracts',
309
+ includePhantomTypeParameters: true,
310
+ packages: [
311
+ // ...
312
+ ],
313
+ };
314
+ ```
315
+
316
+ With this option enabled, phantom type parameters become function arguments:
317
+
318
+ ```typescript
319
+
320
+ return new MoveStruct({
321
+ name: `${$moduleName}::Balance<${T.name}>` as const,
322
+ fields: {
323
+ value: bcs.u64(),
324
+ },
325
+ });
326
+ }
327
+ ```
328
+
329
+ ## Using Generated Code
330
+
331
+ ### Calling Move Functions
332
+
333
+ The generated code provides type-safe functions for calling Move functions:
334
+
335
+ ```typescript
336
+ // Increment a counter
337
+ const tx = new Transaction();
338
+ tx.add(
339
+ counter.increment({
340
+ arguments: {
341
+ counter: '0x123...', // Counter object ID
342
+ },
343
+ }),
344
+ );
345
+ ```
346
+
347
+ ### Parsing BCS Data
348
+
349
+ Use generated BCS types to parse on-chain object data. Fetch the object with
350
+ `include: { content: true }` and pass `object.content` to the generated type's `.parse()` method:
351
+
352
+ ```typescript
353
+ async function readCounter(client: ClientWithCoreApi, id: string) {
354
+ const { object } = await client.core.getObject({
355
+ objectId: id,
356
+ include: { content: true },
357
+ });
358
+
359
+ // Parse the Move struct fields from BCS content
360
+ const parsed = CounterStruct.parse(object.content);
361
+ console.log('Counter value:', parsed.value);
362
+ console.log('Counter owner:', parsed.owner);
363
+
364
+ return parsed;
365
+ }
366
+ ```
367
+
368
+ > **Warning:** Always use `content`, not `objectBcs`, when parsing with generated types. The
369
+ > `objectBcs` field contains a full object envelope with additional metadata that will cause parsing
370
+ > to fail. See the [Core API docs](/haneul/clients/core#objectbcs) for details.
371
+
372
+ ## Client Configuration
373
+
374
+ ### Using with MVR (Move Version Registry)
375
+
376
+ If your package is registered on MVR, the generated code works without additional configuration.
377
+
378
+ ### Local Packages
379
+
380
+ For local packages using `@local-pkg/*` identifiers, configure your client with package overrides:
381
+
382
+ ```typescript
383
+ const client = new HaneulGrpcClient({
384
+ network: 'testnet',
385
+ baseUrl: 'https://fullnode.testnet.haneul.io:443',
386
+ mvr: {
387
+ overrides: {
388
+ packages: {
389
+ '@local-pkg/counter': '0xYOUR_PACKAGE_ID',
390
+ },
391
+ },
392
+ },
393
+ });
394
+ ```
395
+
396
+ ### With dApp Kit
397
+
398
+ Configure package overrides when creating your dApp Kit instance:
399
+
400
+ ```typescript
401
+ const GRPC_URLS = {
402
+ testnet: 'https://fullnode.testnet.haneul.io:443',
403
+ };
404
+
405
+ const PACKAGE_IDS = {
406
+ testnet: {
407
+ counter: '0xYOUR_PACKAGE_ID',
408
+ },
409
+ };
410
+
411
+ const dAppKit = createDAppKit({
412
+ networks: ['testnet'],
413
+ createClient: (network) => {
414
+ return new HaneulGrpcClient({
415
+ network,
416
+ baseUrl: GRPC_URLS[network],
417
+ mvr: {
418
+ overrides: {
419
+ packages: {
420
+ '@local-pkg/counter': PACKAGE_IDS[network].counter,
421
+ },
422
+ },
423
+ },
424
+ });
425
+ },
426
+ });
427
+ ```
428
+
429
+ ## Related Resources
430
+
431
+ - [create-dapp](/dapp-kit/getting-started/create-dapp) - Bootstrap a working dApp with codegen
432
+ already configured
433
+ - [Haneul Move documentation](https://docs.haneul.io/concepts/haneul-move-concepts)
434
+ - [BCS documentation](/bcs)
435
+ - [Transaction building](/haneul/transaction-building/basics)
436
+ - [dApp Kit](/dapp-kit)
@@ -0,0 +1,6 @@
1
+ # TypeScript Codegen
2
+
3
+ > Generate type-safe TypeScript code from Haneul Move packages
4
+
5
+ - [Haneul TypeScript Codegen](./index.md): Generate type-safe TypeScript bindings from on-chain
6
+ Haneul Move packages