@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
@@ -1,16 +1,35 @@
1
- const utilsContent = (
2
- /* ts */
3
- `
4
- import { bcs, BcsType, TypeTag, TypeTagSerializer, BcsStruct, BcsEnum, BcsTuple } from '@haneullabs/haneul/bcs';
1
+ //#region src/generate-utils.ts
2
+ const utilsContent = `
3
+ import {
4
+ bcs,
5
+ BcsType,
6
+ TypeTag,
7
+ TypeTagSerializer,
8
+ BcsStruct,
9
+ BcsEnum,
10
+ BcsTuple,
11
+ } from '@haneullabs/haneul/bcs';
5
12
  import { normalizeHaneulAddress } from '@haneullabs/haneul/utils';
6
13
  import { TransactionArgument, isArgument } from '@haneullabs/haneul/transactions';
14
+ import { ClientWithCoreApi, HaneulClientTypes } from '@haneullabs/haneul/client';
7
15
 
8
16
  const MOVE_STDLIB_ADDRESS = normalizeHaneulAddress('0x1');
9
17
  const HANEUL_FRAMEWORK_ADDRESS = normalizeHaneulAddress('0x2');
10
- const HANEUL_SYSTEM_ADDRESS = normalizeHaneulAddress('0x3');
11
18
 
12
19
  export type RawTransactionArgument<T> = T | TransactionArgument;
13
20
 
21
+ export interface GetOptions<
22
+ Include extends Omit<HaneulClientTypes.ObjectInclude, 'content'> = {},
23
+ > extends HaneulClientTypes.GetObjectOptions<Include> {
24
+ client: ClientWithCoreApi;
25
+ }
26
+
27
+ export interface GetManyOptions<
28
+ Include extends Omit<HaneulClientTypes.ObjectInclude, 'content'> = {},
29
+ > extends HaneulClientTypes.GetObjectsOptions<Include> {
30
+ client: ClientWithCoreApi;
31
+ }
32
+
14
33
  export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null {
15
34
  const parsedTag = typeof typeTag === 'string' ? TypeTagSerializer.parseFromStr(typeTag) : typeTag;
16
35
 
@@ -35,7 +54,7 @@ export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null
35
54
  return type ? bcs.vector(type) : null;
36
55
  } else if ('struct' in parsedTag) {
37
56
  const structTag = parsedTag.struct;
38
- const pkg = normalizeHaneulAddress(parsedTag.struct.address);
57
+ const pkg = normalizeHaneulAddress(structTag.address);
39
58
 
40
59
  if (pkg === MOVE_STDLIB_ADDRESS) {
41
60
  if (
@@ -46,12 +65,16 @@ export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null
46
65
  }
47
66
 
48
67
  if (structTag.module === 'option' && structTag.name === 'Option') {
49
- const type = getPureBcsSchema(structTag.typeParams[0]!);
68
+ const type = getPureBcsSchema(structTag.typeParams[0]);
50
69
  return type ? bcs.option(type) : null;
51
70
  }
52
71
  }
53
72
 
54
- if (pkg === HANEUL_FRAMEWORK_ADDRESS && structTag.module === 'Object' && structTag.name === 'ID') {
73
+ if (
74
+ pkg === HANEUL_FRAMEWORK_ADDRESS &&
75
+ structTag.module === 'object' &&
76
+ (structTag.name === 'ID' || structTag.name === 'UID')
77
+ ) {
55
78
  return bcs.Address;
56
79
  }
57
80
  }
@@ -59,7 +82,11 @@ export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null
59
82
  return null;
60
83
  }
61
84
 
62
- export function normalizeMoveArguments(args: unknown[] | object, argTypes: string[], parameterNames?: string[]) {
85
+ export function normalizeMoveArguments(
86
+ args: unknown[] | object,
87
+ argTypes: readonly (string | null)[],
88
+ parameterNames?: string[],
89
+ ) {
63
90
  const argLen = Array.isArray(args) ? args.length : Object.keys(args).length;
64
91
  if (parameterNames && argLen !== parameterNames.length) {
65
92
  throw new Error(
@@ -71,30 +98,32 @@ export function normalizeMoveArguments(args: unknown[] | object, argTypes: strin
71
98
 
72
99
  let index = 0;
73
100
  for (const [i, argType] of argTypes.entries()) {
74
- if (argType === \`\${HANEUL_FRAMEWORK_ADDRESS}::deny_list::DenyList\`) {
75
- normalizedArgs.push((tx) => tx.object.denyList());
101
+ if (argType === '0x2::clock::Clock') {
102
+ normalizedArgs.push((tx) => tx.object.clock());
76
103
  continue;
77
104
  }
78
105
 
79
- if (argType === \`\${HANEUL_FRAMEWORK_ADDRESS}::random::Random\`) {
106
+ if (argType === '0x2::random::Random') {
80
107
  normalizedArgs.push((tx) => tx.object.random());
81
108
  continue;
82
109
  }
83
110
 
84
- if (argType === \`\${HANEUL_FRAMEWORK_ADDRESS}::clock::Clock\`) {
85
- normalizedArgs.push((tx) => tx.object.clock());
111
+ if (argType === '0x2::deny_list::DenyList') {
112
+ normalizedArgs.push((tx) => tx.object.denyList());
86
113
  continue;
87
114
  }
88
115
 
89
- if (argType === \`\${HANEUL_SYSTEM_ADDRESS}::haneul_system::HaneulSystemState\`) {
116
+ if (argType === '0x3::haneul_system::HaneulSystemState') {
90
117
  normalizedArgs.push((tx) => tx.object.system());
91
118
  continue;
92
119
  }
93
120
 
94
- let arg
121
+ let arg;
95
122
  if (Array.isArray(args)) {
96
123
  if (index >= args.length) {
97
- throw new Error(\`Invalid number of arguments, expected at least \${index + 1}, got \${args.length}\`);
124
+ throw new Error(
125
+ \`Invalid number of arguments, expected at least \${index + 1}, got \${args.length}\`,
126
+ );
98
127
  }
99
128
  arg = args[index];
100
129
  } else {
@@ -116,8 +145,8 @@ export function normalizeMoveArguments(args: unknown[] | object, argTypes: strin
116
145
  continue;
117
146
  }
118
147
 
119
- const type = argTypes[i]!;
120
- const bcsType = getPureBcsSchema(type);
148
+ const type = argTypes[i];
149
+ const bcsType = type === null ? null : getPureBcsSchema(type);
121
150
 
122
151
  if (bcsType) {
123
152
  const bytes = bcsType.serialize(arg as never);
@@ -137,7 +166,47 @@ export function normalizeMoveArguments(args: unknown[] | object, argTypes: strin
137
166
  export class MoveStruct<
138
167
  T extends Record<string, BcsType<any>>,
139
168
  const Name extends string = string,
140
- > extends BcsStruct<T, Name> {}
169
+ > extends BcsStruct<T, Name> {
170
+ async get<Include extends Omit<HaneulClientTypes.ObjectInclude, 'content' | 'json'> = {}>({
171
+ objectId,
172
+ ...options
173
+ }: GetOptions<Include>): Promise<
174
+ HaneulClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }
175
+ > {
176
+ const [res] = await this.getMany<Include>({
177
+ ...options,
178
+ objectIds: [objectId],
179
+ });
180
+
181
+ return res;
182
+ }
183
+
184
+ async getMany<Include extends Omit<HaneulClientTypes.ObjectInclude, 'content' | 'json'> = {}>({
185
+ client,
186
+ ...options
187
+ }: GetManyOptions<Include>): Promise<
188
+ Array<HaneulClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }>
189
+ > {
190
+ const response = (await client.core.getObjects({
191
+ ...options,
192
+ include: {
193
+ ...options.include,
194
+ content: true,
195
+ },
196
+ })) as HaneulClientTypes.GetObjectsResponse<Include & { content: true }>;
197
+
198
+ return response.objects.map((obj) => {
199
+ if (obj instanceof Error) {
200
+ throw obj;
201
+ }
202
+
203
+ return {
204
+ ...obj,
205
+ json: this.parse(obj.content),
206
+ };
207
+ });
208
+ }
209
+ }
141
210
 
142
211
  export class MoveEnum<
143
212
  T extends Record<string, BcsType<any> | null>,
@@ -145,7 +214,7 @@ export class MoveEnum<
145
214
  > extends BcsEnum<T, Name> {}
146
215
 
147
216
  export class MoveTuple<
148
- T extends readonly BcsType<any>[],
217
+ const T extends readonly BcsType<any>[],
149
218
  const Name extends string,
150
219
  > extends BcsTuple<T, Name> {}
151
220
 
@@ -159,9 +228,8 @@ function stringify(val: unknown) {
159
228
 
160
229
  return val;
161
230
  }
162
- `
163
- );
164
- export {
165
- utilsContent
166
- };
167
- //# sourceMappingURL=generate-utils.js.map
231
+ `;
232
+
233
+ //#endregion
234
+ export { utilsContent };
235
+ //# sourceMappingURL=generate-utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-utils.mjs","names":[],"sources":["../src/generate-utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport const utilsContent = /* ts */ `\nimport {\n\tbcs,\n\tBcsType,\n\tTypeTag,\n\tTypeTagSerializer,\n\tBcsStruct,\n\tBcsEnum,\n\tBcsTuple,\n} from '@haneullabs/haneul/bcs';\nimport { normalizeHaneulAddress } from '@haneullabs/haneul/utils';\nimport { TransactionArgument, isArgument } from '@haneullabs/haneul/transactions';\nimport { ClientWithCoreApi, HaneulClientTypes } from '@haneullabs/haneul/client';\n\nconst MOVE_STDLIB_ADDRESS = normalizeHaneulAddress('0x1');\nconst HANEUL_FRAMEWORK_ADDRESS = normalizeHaneulAddress('0x2');\n\nexport type RawTransactionArgument<T> = T | TransactionArgument;\n\nexport interface GetOptions<\n\tInclude extends Omit<HaneulClientTypes.ObjectInclude, 'content'> = {},\n> extends HaneulClientTypes.GetObjectOptions<Include> {\n\tclient: ClientWithCoreApi;\n}\n\nexport interface GetManyOptions<\n\tInclude extends Omit<HaneulClientTypes.ObjectInclude, 'content'> = {},\n> extends HaneulClientTypes.GetObjectsOptions<Include> {\n\tclient: ClientWithCoreApi;\n}\n\nexport function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null {\n\tconst parsedTag = typeof typeTag === 'string' ? TypeTagSerializer.parseFromStr(typeTag) : typeTag;\n\n\tif ('u8' in parsedTag) {\n\t\treturn bcs.U8;\n\t} else if ('u16' in parsedTag) {\n\t\treturn bcs.U16;\n\t} else if ('u32' in parsedTag) {\n\t\treturn bcs.U32;\n\t} else if ('u64' in parsedTag) {\n\t\treturn bcs.U64;\n\t} else if ('u128' in parsedTag) {\n\t\treturn bcs.U128;\n\t} else if ('u256' in parsedTag) {\n\t\treturn bcs.U256;\n\t} else if ('address' in parsedTag) {\n\t\treturn bcs.Address;\n\t} else if ('bool' in parsedTag) {\n\t\treturn bcs.Bool;\n\t} else if ('vector' in parsedTag) {\n\t\tconst type = getPureBcsSchema(parsedTag.vector);\n\t\treturn type ? bcs.vector(type) : null;\n\t} else if ('struct' in parsedTag) {\n\t\tconst structTag = parsedTag.struct;\n\t\tconst pkg = normalizeHaneulAddress(structTag.address);\n\n\t\tif (pkg === MOVE_STDLIB_ADDRESS) {\n\t\t\tif (\n\t\t\t\t(structTag.module === 'ascii' || structTag.module === 'string') &&\n\t\t\t\tstructTag.name === 'String'\n\t\t\t) {\n\t\t\t\treturn bcs.String;\n\t\t\t}\n\n\t\t\tif (structTag.module === 'option' && structTag.name === 'Option') {\n\t\t\t\tconst type = getPureBcsSchema(structTag.typeParams[0]);\n\t\t\t\treturn type ? bcs.option(type) : null;\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\tpkg === HANEUL_FRAMEWORK_ADDRESS &&\n\t\t\tstructTag.module === 'object' &&\n\t\t\t(structTag.name === 'ID' || structTag.name === 'UID')\n\t\t) {\n\t\t\treturn bcs.Address;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nexport function normalizeMoveArguments(\n\targs: unknown[] | object,\n\targTypes: readonly (string | null)[],\n\tparameterNames?: string[],\n) {\n\tconst argLen = Array.isArray(args) ? args.length : Object.keys(args).length;\n\tif (parameterNames && argLen !== parameterNames.length) {\n\t\tthrow new Error(\n\t\t\t\\`Invalid number of arguments, expected \\${parameterNames.length}, got \\${argLen}\\`,\n\t\t);\n\t}\n\n\tconst normalizedArgs: TransactionArgument[] = [];\n\n\tlet index = 0;\n\tfor (const [i, argType] of argTypes.entries()) {\n\t\tif (argType === '0x2::clock::Clock') {\n\t\t\tnormalizedArgs.push((tx) => tx.object.clock());\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (argType === '0x2::random::Random') {\n\t\t\tnormalizedArgs.push((tx) => tx.object.random());\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (argType === '0x2::deny_list::DenyList') {\n\t\t\tnormalizedArgs.push((tx) => tx.object.denyList());\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (argType === '0x3::haneul_system::HaneulSystemState') {\n\t\t\tnormalizedArgs.push((tx) => tx.object.system());\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet arg;\n\t\tif (Array.isArray(args)) {\n\t\t\tif (index >= args.length) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\\`Invalid number of arguments, expected at least \\${index + 1}, got \\${args.length}\\`,\n\t\t\t\t);\n\t\t\t}\n\t\t\targ = args[index];\n\t\t} else {\n\t\t\tif (!parameterNames) {\n\t\t\t\tthrow new Error(\\`Expected arguments to be passed as an array\\`);\n\t\t\t}\n\t\t\tconst name = parameterNames[index];\n\t\t\targ = args[name as keyof typeof args];\n\n\t\t\tif (arg === undefined) {\n\t\t\t\tthrow new Error(\\`Parameter \\${name} is required\\`);\n\t\t\t}\n\t\t}\n\n\t\tindex += 1;\n\n\t\tif (typeof arg === 'function' || isArgument(arg)) {\n\t\t\tnormalizedArgs.push(arg as TransactionArgument);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst type = argTypes[i];\n\t\tconst bcsType = type === null ? null : getPureBcsSchema(type);\n\n\t\tif (bcsType) {\n\t\t\tconst bytes = bcsType.serialize(arg as never);\n\t\t\tnormalizedArgs.push((tx) => tx.pure(bytes));\n\t\t\tcontinue;\n\t\t} else if (typeof arg === 'string') {\n\t\t\tnormalizedArgs.push((tx) => tx.object(arg));\n\t\t\tcontinue;\n\t\t}\n\n\t\tthrow new Error(\\`Invalid argument \\${stringify(arg)} for type \\${type}\\`);\n\t}\n\n\treturn normalizedArgs;\n}\n\nexport class MoveStruct<\n\tT extends Record<string, BcsType<any>>,\n\tconst Name extends string = string,\n> extends BcsStruct<T, Name> {\n\tasync get<Include extends Omit<HaneulClientTypes.ObjectInclude, 'content' | 'json'> = {}>({\n\t\tobjectId,\n\t\t...options\n\t}: GetOptions<Include>): Promise<\n\t\tHaneulClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }\n\t> {\n\t\tconst [res] = await this.getMany<Include>({\n\t\t\t...options,\n\t\t\tobjectIds: [objectId],\n\t\t});\n\n\t\treturn res;\n\t}\n\n\tasync getMany<Include extends Omit<HaneulClientTypes.ObjectInclude, 'content' | 'json'> = {}>({\n\t\tclient,\n\t\t...options\n\t}: GetManyOptions<Include>): Promise<\n\t\tArray<HaneulClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }>\n\t> {\n\t\tconst response = (await client.core.getObjects({\n\t\t\t...options,\n\t\t\tinclude: {\n\t\t\t\t...options.include,\n\t\t\t\tcontent: true,\n\t\t\t},\n\t\t})) as HaneulClientTypes.GetObjectsResponse<Include & { content: true }>;\n\n\t\treturn response.objects.map((obj) => {\n\t\t\tif (obj instanceof Error) {\n\t\t\t\tthrow obj;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...obj,\n\t\t\t\tjson: this.parse(obj.content),\n\t\t\t};\n\t\t});\n\t}\n}\n\nexport class MoveEnum<\n\tT extends Record<string, BcsType<any> | null>,\n\tconst Name extends string,\n> extends BcsEnum<T, Name> {}\n\nexport class MoveTuple<\n\tconst T extends readonly BcsType<any>[],\n\tconst Name extends string,\n> extends BcsTuple<T, Name> {}\n\nfunction stringify(val: unknown) {\n\tif (typeof val === 'object') {\n\t\treturn JSON.stringify(val, (val: unknown) => val);\n\t}\n\tif (typeof val === 'bigint') {\n\t\treturn val.toString();\n\t}\n\n\treturn val;\n}\n`;\n"],"mappings":";AAGA,MAAa,eAAwB"}
@@ -0,0 +1,21 @@
1
+ import { GenerateBase, HaneulCodegenConfig, ImportExtension, PackageConfig } from "./config.mjs";
2
+
3
+ //#region src/index.d.ts
4
+ declare function generateFromPackageSummary({
5
+ package: pkg,
6
+ prune,
7
+ outputDir,
8
+ globalGenerate,
9
+ importExtension,
10
+ includePhantomTypeParameters
11
+ }: {
12
+ package: PackageConfig;
13
+ prune: boolean;
14
+ outputDir: string;
15
+ globalGenerate?: GenerateBase;
16
+ importExtension?: ImportExtension;
17
+ includePhantomTypeParameters?: boolean;
18
+ }): Promise<void>;
19
+ //#endregion
20
+ export { type HaneulCodegenConfig, generateFromPackageSummary };
21
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;iBAmBsB,0BAAA,CAAA;EACrB,OAAA,EAAS,GAAA;EACT,KAAA;EACA,SAAA;EACA,cAAA;EACA,eAAA;EACA;AAAA;EAEA,OAAA,EAAS,aAAA;EACT,KAAA;EACA,SAAA;EACA,cAAA,GAAiB,YAAA;EACjB,eAAA,GAAkB,eAAA;EAClB,4BAAA;AAAA,IACA,OAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,80 @@
1
+ import { MoveModuleBuilder } from "./move-module-builder.mjs";
2
+ import { utilsContent } from "./generate-utils.mjs";
3
+ import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
4
+ import { basename, join } from "node:path";
5
+ import { existsSync, statSync } from "node:fs";
6
+ import { parse } from "toml";
7
+
8
+ //#region src/index.ts
9
+ async function generateFromPackageSummary({ package: pkg, prune, outputDir, globalGenerate, importExtension = ".js", includePhantomTypeParameters = false }) {
10
+ if (!pkg.path) throw new Error(`Package path is required (got ${pkg.package})`);
11
+ const localSummaryDir = join(pkg.path, "package_summaries");
12
+ const isOnChainPackage = existsSync(join(pkg.path, "root_package_metadata.json"));
13
+ const summaryDir = isOnChainPackage ? pkg.path : localSummaryDir;
14
+ if (!existsSync(summaryDir) || !existsSync(join(summaryDir, "address_mapping.json"))) throw new Error(`Package summary directory not found: ${summaryDir}`);
15
+ let packageName = pkg.packageName;
16
+ let mainPackageAddress;
17
+ const mvrNameOrAddress = pkg.package;
18
+ if (isOnChainPackage) {
19
+ mainPackageAddress = JSON.parse(await readFile(join(pkg.path, "root_package_metadata.json"), "utf-8")).root_package_id;
20
+ if (!packageName) packageName = mainPackageAddress;
21
+ } else if (!pkg.packageName) try {
22
+ packageName = parse(await readFile(join(pkg.path, "Move.toml"), "utf-8")).package.name.toLowerCase();
23
+ } catch {
24
+ const message = `Package name not found in package.toml for ${pkg.path}`;
25
+ if (packageName) console.warn(message);
26
+ else throw new Error(message);
27
+ }
28
+ const addressMappings = JSON.parse(await readFile(join(summaryDir, "address_mapping.json"), "utf-8"));
29
+ const packages = (await readdir(summaryDir)).filter((file) => statSync(join(summaryDir, file)).isDirectory());
30
+ const isMainPackage = (pkgDir) => {
31
+ if (isOnChainPackage) return pkgDir === mainPackageAddress;
32
+ return pkgDir === packageName;
33
+ };
34
+ const modules = (await Promise.all(packages.map(async (pkgDir) => {
35
+ const moduleFiles = await readdir(join(summaryDir, pkgDir));
36
+ return Promise.all(moduleFiles.filter((f) => f.endsWith(".json")).map(async (mod) => ({
37
+ package: pkgDir,
38
+ isMainPackage: isMainPackage(pkgDir),
39
+ module: basename(mod, ".json"),
40
+ builder: await MoveModuleBuilder.fromSummaryFile(join(summaryDir, pkgDir, mod), addressMappings, isMainPackage(pkgDir) ? mvrNameOrAddress : void 0, importExtension, includePhantomTypeParameters)
41
+ })));
42
+ }))).flat();
43
+ const moduleBuilders = Object.fromEntries(modules.map((mod) => [`${mod.package}::${mod.module}`, mod.builder]));
44
+ const packageGenerate = "generate" in pkg ? pkg.generate : void 0;
45
+ const pkgModules = packageGenerate?.modules;
46
+ const pkgTypes = packageGenerate?.types ?? globalGenerate?.types ?? true;
47
+ const pkgFunctions = packageGenerate?.functions ?? globalGenerate?.functions ?? true;
48
+ for (const mod of modules) {
49
+ if (!mod.isMainPackage && prune) continue;
50
+ const moduleGenerate = !pkgModules ? true : Array.isArray(pkgModules) ? pkgModules.includes(mod.module) || null : mod.module in pkgModules ? pkgModules[mod.module] : null;
51
+ if (!moduleGenerate) continue;
52
+ const types = moduleGenerate === true ? pkgTypes : moduleGenerate.types ?? false;
53
+ const functions = moduleGenerate === true ? pkgFunctions : moduleGenerate.functions ?? false;
54
+ mod.builder.includeTypes(moduleBuilders, types);
55
+ mod.builder.includeFunctions(functions);
56
+ }
57
+ await generateUtils({ outputDir });
58
+ await rm(join(outputDir, packageName), {
59
+ recursive: true,
60
+ force: true
61
+ });
62
+ await Promise.all(modules.map(async (mod) => {
63
+ if ((mod.isMainPackage || !prune) && mod.builder.hasTypesOrFunctions()) {
64
+ await mod.builder.renderBCSTypes();
65
+ await mod.builder.renderFunctions();
66
+ } else if (mod.isMainPackage) return;
67
+ else if (mod.builder.hasBcsTypes()) await mod.builder.renderBCSTypes();
68
+ else return;
69
+ await mkdir(mod.isMainPackage ? join(outputDir, packageName) : join(outputDir, packageName, "deps", mod.package), { recursive: true });
70
+ await writeFile(mod.isMainPackage ? join(outputDir, packageName, `${mod.module}.ts`) : join(outputDir, packageName, "deps", mod.package, `${mod.module}.ts`), await mod.builder.toString("./", mod.isMainPackage ? `./${mod.module}.ts` : `./deps/${mod.package}/${mod.module}.ts`));
71
+ }));
72
+ }
73
+ async function generateUtils({ outputDir }) {
74
+ await mkdir(join(outputDir, "utils"), { recursive: true });
75
+ await writeFile(join(outputDir, "utils", "index.ts"), utilsContent);
76
+ }
77
+
78
+ //#endregion
79
+ export { generateFromPackageSummary };
80
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport { MoveModuleBuilder } from './move-module-builder.js';\nimport { existsSync, statSync } from 'node:fs';\nimport { utilsContent } from './generate-utils.js';\nimport { parse } from 'toml';\nimport type {\n\tFunctionsOption,\n\tGenerateBase,\n\tImportExtension,\n\tPackageConfig,\n\tPackageGenerate,\n\tTypesOption,\n} from './config.js';\nexport { type HaneulCodegenConfig } from './config.js';\n\nexport async function generateFromPackageSummary({\n\tpackage: pkg,\n\tprune,\n\toutputDir,\n\tglobalGenerate,\n\timportExtension = '.js',\n\tincludePhantomTypeParameters = false,\n}: {\n\tpackage: PackageConfig;\n\tprune: boolean;\n\toutputDir: string;\n\tglobalGenerate?: GenerateBase;\n\timportExtension?: ImportExtension;\n\tincludePhantomTypeParameters?: boolean;\n}) {\n\tif (!pkg.path) {\n\t\tthrow new Error(`Package path is required (got ${pkg.package})`);\n\t}\n\n\t// Check for on-chain package summary (directly in path) or local package summary (in package_summaries subdirectory)\n\tconst localSummaryDir = join(pkg.path, 'package_summaries');\n\tconst isOnChainPackage = existsSync(join(pkg.path, 'root_package_metadata.json'));\n\tconst summaryDir = isOnChainPackage ? pkg.path : localSummaryDir;\n\n\tif (!existsSync(summaryDir) || !existsSync(join(summaryDir, 'address_mapping.json'))) {\n\t\tthrow new Error(`Package summary directory not found: ${summaryDir}`);\n\t}\n\n\tlet packageName = pkg.packageName!;\n\tlet mainPackageAddress: string | undefined;\n\tconst mvrNameOrAddress = pkg.package;\n\n\tif (isOnChainPackage) {\n\t\t// For on-chain packages, get the main package address from root_package_metadata.json\n\t\tconst metadata = JSON.parse(\n\t\t\tawait readFile(join(pkg.path, 'root_package_metadata.json'), 'utf-8'),\n\t\t);\n\t\tmainPackageAddress = metadata.root_package_id;\n\t\t// Use the package name provided or fall back to the full address\n\t\tif (!packageName) {\n\t\t\tpackageName = mainPackageAddress!;\n\t\t}\n\t} else if (!pkg.packageName) {\n\t\ttry {\n\t\t\tconst packageToml = await readFile(join(pkg.path, 'Move.toml'), 'utf-8');\n\t\t\tpackageName = parse(packageToml).package.name.toLowerCase();\n\t\t} catch {\n\t\t\tconst message = `Package name not found in package.toml for ${pkg.path}`;\n\t\t\tif (packageName) {\n\t\t\t\tconsole.warn(message);\n\t\t\t} else {\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst addressMappings: Record<string, string> = JSON.parse(\n\t\tawait readFile(join(summaryDir, 'address_mapping.json'), 'utf-8'),\n\t);\n\n\tconst packages = (await readdir(summaryDir)).filter((file) =>\n\t\tstatSync(join(summaryDir, file)).isDirectory(),\n\t);\n\n\t// For on-chain packages, the main package is identified by the root_package_id\n\t// For local packages, it's identified by the packageName\n\tconst isMainPackage = (pkgDir: string) => {\n\t\tif (isOnChainPackage) {\n\t\t\treturn pkgDir === mainPackageAddress;\n\t\t}\n\t\treturn pkgDir === packageName;\n\t};\n\n\tconst modules = (\n\t\tawait Promise.all(\n\t\t\tpackages.map(async (pkgDir) => {\n\t\t\t\tconst moduleFiles = await readdir(join(summaryDir, pkgDir));\n\t\t\t\treturn Promise.all(\n\t\t\t\t\tmoduleFiles\n\t\t\t\t\t\t.filter((f) => f.endsWith('.json'))\n\t\t\t\t\t\t.map(async (mod) => ({\n\t\t\t\t\t\t\tpackage: pkgDir,\n\t\t\t\t\t\t\tisMainPackage: isMainPackage(pkgDir),\n\t\t\t\t\t\t\tmodule: basename(mod, '.json'),\n\t\t\t\t\t\t\tbuilder: await MoveModuleBuilder.fromSummaryFile(\n\t\t\t\t\t\t\t\tjoin(summaryDir, pkgDir, mod),\n\t\t\t\t\t\t\t\taddressMappings,\n\t\t\t\t\t\t\t\tisMainPackage(pkgDir) ? mvrNameOrAddress : undefined,\n\t\t\t\t\t\t\t\timportExtension,\n\t\t\t\t\t\t\t\tincludePhantomTypeParameters,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}),\n\t\t)\n\t).flat();\n\n\tconst moduleBuilders = Object.fromEntries(\n\t\tmodules.map((mod) => [`${mod.package}::${mod.module}`, mod.builder]),\n\t);\n\n\tconst packageGenerate: PackageGenerate | undefined = 'generate' in pkg ? pkg.generate : undefined;\n\tconst pkgModules = packageGenerate?.modules;\n\tconst pkgTypes: TypesOption = packageGenerate?.types ?? globalGenerate?.types ?? true;\n\tconst pkgFunctions: FunctionsOption =\n\t\tpackageGenerate?.functions ?? globalGenerate?.functions ?? true;\n\n\tfor (const mod of modules) {\n\t\tif (!mod.isMainPackage && prune) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst moduleGenerate = !pkgModules\n\t\t\t? true\n\t\t\t: Array.isArray(pkgModules)\n\t\t\t\t? pkgModules.includes(mod.module) || null\n\t\t\t\t: mod.module in pkgModules\n\t\t\t\t\t? pkgModules[mod.module]\n\t\t\t\t\t: null;\n\n\t\tif (!moduleGenerate) continue;\n\n\t\tconst types = moduleGenerate === true ? pkgTypes : (moduleGenerate.types ?? false);\n\t\tconst functions = moduleGenerate === true ? pkgFunctions : (moduleGenerate.functions ?? false);\n\n\t\tmod.builder.includeTypes(moduleBuilders, types);\n\t\tmod.builder.includeFunctions(functions);\n\t}\n\n\tawait generateUtils({ outputDir });\n\n\t// Clean the package output directory to remove stale files from previous runs\n\tconst packageOutputDir = join(outputDir, packageName);\n\tawait rm(packageOutputDir, { recursive: true, force: true });\n\n\tawait Promise.all(\n\t\tmodules.map(async (mod) => {\n\t\t\tif ((mod.isMainPackage || !prune) && mod.builder.hasTypesOrFunctions()) {\n\t\t\t\tawait mod.builder.renderBCSTypes();\n\t\t\t\tawait mod.builder.renderFunctions();\n\t\t\t} else if (mod.isMainPackage) {\n\t\t\t\treturn;\n\t\t\t} else if (mod.builder.hasBcsTypes()) {\n\t\t\t\tawait mod.builder.renderBCSTypes();\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait mkdir(\n\t\t\t\tmod.isMainPackage\n\t\t\t\t\t? join(outputDir, packageName)\n\t\t\t\t\t: join(outputDir, packageName, 'deps', mod.package),\n\t\t\t\t{ recursive: true },\n\t\t\t);\n\n\t\t\tawait writeFile(\n\t\t\t\tmod.isMainPackage\n\t\t\t\t\t? join(outputDir, packageName, `${mod.module}.ts`)\n\t\t\t\t\t: join(outputDir, packageName, 'deps', mod.package, `${mod.module}.ts`),\n\t\t\t\tawait mod.builder.toString(\n\t\t\t\t\t'./',\n\t\t\t\t\tmod.isMainPackage ? `./${mod.module}.ts` : `./deps/${mod.package}/${mod.module}.ts`,\n\t\t\t\t),\n\t\t\t);\n\t\t}),\n\t);\n}\n\nasync function generateUtils({ outputDir }: { outputDir: string }) {\n\tawait mkdir(join(outputDir, 'utils'), { recursive: true });\n\tawait writeFile(join(outputDir, 'utils', 'index.ts'), utilsContent);\n}\n"],"mappings":"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"}