@haneullabs/codegen 0.1.0 → 0.8.2
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.
- package/CHANGELOG.md +128 -33
- package/README.md +35 -33
- package/dist/bin/bash-complete.d.mts +6 -0
- package/dist/bin/bash-complete.d.mts.map +1 -0
- package/dist/bin/bash-complete.mjs +29 -0
- package/dist/bin/bash-complete.mjs.map +1 -0
- package/dist/bin/cli.d.mts +1 -0
- package/dist/bin/cli.mjs +24 -0
- package/dist/bin/cli.mjs.map +1 -0
- package/dist/cli/cli.mjs +28 -0
- package/dist/cli/cli.mjs.map +1 -0
- package/dist/cli/commands/generate/command.mjs +90 -0
- package/dist/cli/commands/generate/command.mjs.map +1 -0
- package/dist/cli/commands/generate/impl.mjs +72 -0
- package/dist/cli/commands/generate/impl.mjs.map +1 -0
- package/dist/cli/context.mjs +17 -0
- package/dist/cli/context.mjs.map +1 -0
- package/dist/config.d.mts +106 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +70 -0
- package/dist/config.mjs.map +1 -0
- package/dist/file-builder.mjs +65 -0
- package/dist/file-builder.mjs.map +1 -0
- package/dist/{esm/generate-utils.js → generate-utils.mjs} +95 -27
- package/dist/generate-utils.mjs.map +1 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +80 -0
- package/dist/index.mjs.map +1 -0
- package/dist/move-module-builder.mjs +350 -0
- package/dist/move-module-builder.mjs.map +1 -0
- package/dist/render-types.mjs +207 -0
- package/dist/render-types.mjs.map +1 -0
- package/dist/utils.mjs +89 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +27 -28
- package/src/bin/bash-complete.ts +18 -7
- package/src/bin/cli.ts +3 -9
- package/src/cli/commands/generate/command.ts +32 -0
- package/src/cli/commands/generate/impl.ts +93 -5
- package/src/config.ts +55 -7
- package/src/file-builder.ts +14 -1
- package/src/generate-utils.ts +88 -18
- package/src/index.ts +89 -29
- package/src/move-module-builder.ts +181 -76
- package/src/render-types.ts +82 -29
- package/dist/cjs/bin/bash-complete.d.ts +0 -2
- package/dist/cjs/bin/bash-complete.js +0 -51
- package/dist/cjs/bin/bash-complete.js.map +0 -7
- package/dist/cjs/bin/cli.d.ts +0 -2
- package/dist/cjs/bin/cli.js +0 -34
- package/dist/cjs/bin/cli.js.map +0 -7
- package/dist/cjs/cli/cli.d.ts +0 -1
- package/dist/cjs/cli/cli.js +0 -49
- package/dist/cjs/cli/cli.js.map +0 -7
- package/dist/cjs/cli/commands/generate/command.d.ts +0 -1
- package/dist/cjs/cli/commands/generate/command.js +0 -80
- package/dist/cjs/cli/commands/generate/command.js.map +0 -7
- package/dist/cjs/cli/commands/generate/impl.d.ts +0 -8
- package/dist/cjs/cli/commands/generate/impl.js +0 -66
- package/dist/cjs/cli/commands/generate/impl.js.map +0 -7
- package/dist/cjs/cli/context.d.ts +0 -6
- package/dist/cjs/cli/context.js +0 -45
- package/dist/cjs/cli/context.js.map +0 -7
- package/dist/cjs/config.d.ts +0 -51
- package/dist/cjs/config.js +0 -75
- package/dist/cjs/config.js.map +0 -7
- package/dist/cjs/file-builder.d.ts +0 -13
- package/dist/cjs/file-builder.js +0 -83
- package/dist/cjs/file-builder.js.map +0 -7
- package/dist/cjs/generate-utils.d.ts +0 -1
- package/dist/cjs/generate-utils.js +0 -187
- package/dist/cjs/generate-utils.js.map +0 -7
- package/dist/cjs/index.d.ts +0 -8
- package/dist/cjs/index.js +0 -124
- package/dist/cjs/index.js.map +0 -7
- package/dist/cjs/move-module-builder.d.ts +0 -26
- package/dist/cjs/move-module-builder.js +0 -464
- package/dist/cjs/move-module-builder.js.map +0 -7
- package/dist/cjs/package.json +0 -5
- package/dist/cjs/render-types.d.ts +0 -19
- package/dist/cjs/render-types.js +0 -313
- package/dist/cjs/render-types.js.map +0 -7
- package/dist/cjs/summary.d.ts +0 -3
- package/dist/cjs/summary.js +0 -218
- package/dist/cjs/summary.js.map +0 -7
- package/dist/cjs/types/deserialized.d.ts +0 -89
- package/dist/cjs/types/deserialized.js +0 -17
- package/dist/cjs/types/deserialized.js.map +0 -7
- package/dist/cjs/types/summary.d.ts +0 -105
- package/dist/cjs/types/summary.js +0 -17
- package/dist/cjs/types/summary.js.map +0 -7
- package/dist/cjs/utils.d.ts +0 -22
- package/dist/cjs/utils.js +0 -164
- package/dist/cjs/utils.js.map +0 -7
- package/dist/esm/bin/bash-complete.d.ts +0 -2
- package/dist/esm/bin/bash-complete.js +0 -31
- package/dist/esm/bin/bash-complete.js.map +0 -7
- package/dist/esm/bin/cli.d.ts +0 -2
- package/dist/esm/bin/cli.js +0 -32
- package/dist/esm/bin/cli.js.map +0 -7
- package/dist/esm/cli/cli.d.ts +0 -1
- package/dist/esm/cli/cli.js +0 -29
- package/dist/esm/cli/cli.js.map +0 -7
- package/dist/esm/cli/commands/generate/command.d.ts +0 -1
- package/dist/esm/cli/commands/generate/command.js +0 -50
- package/dist/esm/cli/commands/generate/command.js.map +0 -7
- package/dist/esm/cli/commands/generate/impl.d.ts +0 -8
- package/dist/esm/cli/commands/generate/impl.js +0 -46
- package/dist/esm/cli/commands/generate/impl.js.map +0 -7
- package/dist/esm/cli/context.d.ts +0 -6
- package/dist/esm/cli/context.js +0 -15
- package/dist/esm/cli/context.js.map +0 -7
- package/dist/esm/config.d.ts +0 -51
- package/dist/esm/config.js +0 -45
- package/dist/esm/config.js.map +0 -7
- package/dist/esm/file-builder.d.ts +0 -13
- package/dist/esm/file-builder.js +0 -63
- package/dist/esm/file-builder.js.map +0 -7
- package/dist/esm/generate-utils.d.ts +0 -1
- package/dist/esm/generate-utils.js.map +0 -7
- package/dist/esm/index.d.ts +0 -8
- package/dist/esm/index.js +0 -104
- package/dist/esm/index.js.map +0 -7
- package/dist/esm/move-module-builder.d.ts +0 -26
- package/dist/esm/move-module-builder.js +0 -457
- package/dist/esm/move-module-builder.js.map +0 -7
- package/dist/esm/package.json +0 -5
- package/dist/esm/render-types.d.ts +0 -19
- package/dist/esm/render-types.js +0 -293
- package/dist/esm/render-types.js.map +0 -7
- package/dist/esm/summary.d.ts +0 -3
- package/dist/esm/summary.js +0 -198
- package/dist/esm/summary.js.map +0 -7
- package/dist/esm/types/deserialized.d.ts +0 -89
- package/dist/esm/types/deserialized.js +0 -1
- package/dist/esm/types/deserialized.js.map +0 -7
- package/dist/esm/types/summary.d.ts +0 -105
- package/dist/esm/types/summary.js +0 -1
- package/dist/esm/types/summary.js.map +0 -7
- package/dist/esm/utils.d.ts +0 -22
- package/dist/esm/utils.js +0 -134
- package/dist/esm/utils.js.map +0 -7
- package/dist/tsconfig.esm.tsbuildinfo +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -3,16 +3,23 @@
|
|
|
3
3
|
|
|
4
4
|
import type { LocalContext } from '../../context.js';
|
|
5
5
|
import { generateFromPackageSummary } from '../../../index.js';
|
|
6
|
-
import { loadConfig } from '../../../config.js';
|
|
6
|
+
import { loadConfig, type GenerateBase, type PackageGenerate } from '../../../config.js';
|
|
7
7
|
import { isValidNamedPackage, isValidHaneulObjectId } from '@haneullabs/haneul/utils';
|
|
8
8
|
import { execSync } from 'node:child_process';
|
|
9
|
-
import { existsSync } from 'node:fs';
|
|
9
|
+
import { existsSync, mkdtempSync } from 'node:fs';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { join } from 'node:path';
|
|
10
12
|
|
|
11
13
|
export interface SubdirCommandFlags {
|
|
12
14
|
outputDir?: string;
|
|
13
15
|
noPrune?: boolean;
|
|
14
16
|
noSummaries?: boolean;
|
|
15
17
|
network?: 'mainnet' | 'testnet';
|
|
18
|
+
importExtension?: '.js' | '.ts' | 'none';
|
|
19
|
+
modules?: string[];
|
|
20
|
+
noTypes?: boolean;
|
|
21
|
+
noFunctions?: boolean;
|
|
22
|
+
private?: 'none' | 'entry' | 'all';
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
export default async function generate(
|
|
@@ -31,6 +38,7 @@ export default async function generate(
|
|
|
31
38
|
network: flags.network ?? 'testnet',
|
|
32
39
|
packageName: isValidHaneulObjectId(trimmed) ? trimmed : trimmed.split('/')[1],
|
|
33
40
|
package: trimmed,
|
|
41
|
+
packageId: isValidHaneulObjectId(trimmed) ? trimmed : undefined,
|
|
34
42
|
};
|
|
35
43
|
} else {
|
|
36
44
|
return {
|
|
@@ -45,8 +53,53 @@ export default async function generate(
|
|
|
45
53
|
const generateSummaries =
|
|
46
54
|
flags.noSummaries === undefined ? config.generateSummaries : !flags.noSummaries;
|
|
47
55
|
|
|
56
|
+
const cliPrivate =
|
|
57
|
+
flags.private !== undefined
|
|
58
|
+
? flags.private === 'all'
|
|
59
|
+
? true
|
|
60
|
+
: flags.private === 'none'
|
|
61
|
+
? false
|
|
62
|
+
: 'entry'
|
|
63
|
+
: undefined;
|
|
64
|
+
|
|
65
|
+
const cliGenerate: PackageGenerate | undefined =
|
|
66
|
+
flags.modules !== undefined ||
|
|
67
|
+
flags.noTypes !== undefined ||
|
|
68
|
+
flags.noFunctions !== undefined ||
|
|
69
|
+
flags.private !== undefined
|
|
70
|
+
? {
|
|
71
|
+
...(flags.modules !== undefined && { modules: flags.modules }),
|
|
72
|
+
...(flags.noTypes !== undefined && { types: !flags.noTypes as boolean }),
|
|
73
|
+
...(flags.noFunctions !== undefined || flags.private !== undefined
|
|
74
|
+
? {
|
|
75
|
+
functions: flags.noFunctions
|
|
76
|
+
? false
|
|
77
|
+
: cliPrivate !== undefined
|
|
78
|
+
? { private: cliPrivate }
|
|
79
|
+
: true,
|
|
80
|
+
}
|
|
81
|
+
: {}),
|
|
82
|
+
}
|
|
83
|
+
: undefined;
|
|
84
|
+
|
|
48
85
|
for (const pkg of normalizedPackages) {
|
|
49
|
-
|
|
86
|
+
// Detect on-chain packages: they have 'network' field and no 'path'
|
|
87
|
+
const isOnChainPackage =
|
|
88
|
+
('packageId' in pkg && pkg.packageId) || ('network' in pkg && !('path' in pkg));
|
|
89
|
+
|
|
90
|
+
// Generate summaries for on-chain packages using --package-id
|
|
91
|
+
if (isOnChainPackage) {
|
|
92
|
+
const packageId = 'packageId' in pkg ? pkg.packageId : pkg.package;
|
|
93
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'haneul-codegen-'));
|
|
94
|
+
console.log(`Generating summary for on-chain package ${packageId} to ${tempDir}`);
|
|
95
|
+
|
|
96
|
+
execSync(`haneul move summary --package-id ${packageId} --output-directory ${tempDir}`, {
|
|
97
|
+
stdio: 'inherit',
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Set the path to use the generated summary directory
|
|
101
|
+
(pkg as { path?: string }).path = tempDir;
|
|
102
|
+
} else if (generateSummaries && pkg.path) {
|
|
50
103
|
if (!existsSync(pkg.path)) {
|
|
51
104
|
throw new Error(`Package path does not exist: ${pkg.path}`);
|
|
52
105
|
}
|
|
@@ -56,11 +109,46 @@ export default async function generate(
|
|
|
56
109
|
stdio: 'inherit',
|
|
57
110
|
});
|
|
58
111
|
}
|
|
112
|
+
const importExtension =
|
|
113
|
+
flags.importExtension === undefined
|
|
114
|
+
? config.importExtension
|
|
115
|
+
: flags.importExtension === 'none'
|
|
116
|
+
? ''
|
|
117
|
+
: flags.importExtension;
|
|
118
|
+
|
|
119
|
+
const pkgWithOverrides = cliGenerate
|
|
120
|
+
? {
|
|
121
|
+
...pkg,
|
|
122
|
+
generate: {
|
|
123
|
+
...('generate' in pkg ? pkg.generate : {}),
|
|
124
|
+
...cliGenerate,
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
: pkg;
|
|
128
|
+
|
|
129
|
+
// Fold deprecated privateMethods into globalGenerate
|
|
130
|
+
const globalGenerate: GenerateBase | undefined =
|
|
131
|
+
config.privateMethods && !config.generate?.functions
|
|
132
|
+
? {
|
|
133
|
+
...config.generate,
|
|
134
|
+
functions: {
|
|
135
|
+
private:
|
|
136
|
+
config.privateMethods === 'all'
|
|
137
|
+
? true
|
|
138
|
+
: config.privateMethods === 'none'
|
|
139
|
+
? false
|
|
140
|
+
: 'entry',
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
: config.generate;
|
|
144
|
+
|
|
59
145
|
await generateFromPackageSummary({
|
|
60
|
-
package:
|
|
146
|
+
package: pkgWithOverrides,
|
|
61
147
|
prune: flags.noPrune === undefined ? config.prune : !flags.noPrune,
|
|
62
148
|
outputDir: flags.outputDir ?? config.output,
|
|
63
|
-
|
|
149
|
+
globalGenerate,
|
|
150
|
+
importExtension,
|
|
151
|
+
includePhantomTypeParameters: config.includePhantomTypeParameters,
|
|
64
152
|
});
|
|
65
153
|
}
|
|
66
154
|
}
|
package/src/config.ts
CHANGED
|
@@ -5,6 +5,42 @@ import { isValidNamedPackage, isValidHaneulObjectId } from '@haneullabs/haneul/u
|
|
|
5
5
|
import { cosmiconfig } from 'cosmiconfig';
|
|
6
6
|
import * as z from 'zod/v4';
|
|
7
7
|
|
|
8
|
+
export const globalFunctionsOptionSchema = z.union([
|
|
9
|
+
z.boolean(),
|
|
10
|
+
z.object({
|
|
11
|
+
private: z.union([z.boolean(), z.literal('entry')]).optional(),
|
|
12
|
+
}),
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
export const functionsOptionSchema = z.union([
|
|
16
|
+
z.boolean(),
|
|
17
|
+
z.array(z.string()),
|
|
18
|
+
z.object({
|
|
19
|
+
private: z.union([z.boolean(), z.literal('entry')]).optional(),
|
|
20
|
+
}),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
export const typesOptionSchema = z.union([z.boolean(), z.array(z.string())]);
|
|
24
|
+
|
|
25
|
+
export const globalGenerateSchema = z.object({
|
|
26
|
+
functions: globalFunctionsOptionSchema.optional(),
|
|
27
|
+
types: z.boolean().optional(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const moduleGenerateSchema = z.object({
|
|
31
|
+
functions: functionsOptionSchema.optional(),
|
|
32
|
+
types: typesOptionSchema.optional(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const packageGenerateSchema = globalGenerateSchema.extend({
|
|
36
|
+
modules: z
|
|
37
|
+
.union([
|
|
38
|
+
z.array(z.string()),
|
|
39
|
+
z.record(z.string(), z.union([z.literal(true), moduleGenerateSchema])),
|
|
40
|
+
])
|
|
41
|
+
.optional(),
|
|
42
|
+
});
|
|
43
|
+
|
|
8
44
|
export const onChainPackageSchema = z.object({
|
|
9
45
|
package: z.string().refine((name) => isValidNamedPackage(name) || isValidHaneulObjectId(name), {
|
|
10
46
|
message: 'Invalid package name or package ID',
|
|
@@ -12,32 +48,43 @@ export const onChainPackageSchema = z.object({
|
|
|
12
48
|
packageName: z.string(),
|
|
13
49
|
path: z.never().optional(),
|
|
14
50
|
network: z.enum(['mainnet', 'testnet']),
|
|
51
|
+
generate: packageGenerateSchema.optional(),
|
|
15
52
|
});
|
|
16
53
|
|
|
17
54
|
export const localPackageSchema = z.object({
|
|
18
55
|
path: z.string(),
|
|
19
56
|
package: z.string(),
|
|
20
57
|
packageName: z.string().optional(),
|
|
58
|
+
generate: packageGenerateSchema.optional(),
|
|
21
59
|
});
|
|
22
60
|
|
|
23
61
|
export const packageConfigSchema = z.union([onChainPackageSchema, localPackageSchema]);
|
|
24
62
|
|
|
63
|
+
export const importExtensionSchema = z.union([z.literal('.js'), z.literal('.ts'), z.literal('')]);
|
|
64
|
+
export type ImportExtension = z.infer<typeof importExtensionSchema>;
|
|
65
|
+
|
|
66
|
+
export type GenerateBase = z.infer<typeof globalGenerateSchema>;
|
|
67
|
+
export type PackageGenerate = z.infer<typeof packageGenerateSchema>;
|
|
68
|
+
export type FunctionsOption = z.infer<typeof functionsOptionSchema>;
|
|
69
|
+
export type TypesOption = z.infer<typeof typesOptionSchema>;
|
|
70
|
+
|
|
25
71
|
export const configSchema = z.object({
|
|
26
72
|
output: z.string(),
|
|
27
73
|
prune: z.boolean().optional().default(true),
|
|
28
74
|
generateSummaries: z.boolean().optional().default(true),
|
|
29
75
|
packages: z.array(packageConfigSchema),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
76
|
+
generate: globalGenerateSchema.optional(),
|
|
77
|
+
/** @deprecated Use `generate: { functions: { private: 'entry' } }` instead */
|
|
78
|
+
privateMethods: z.union([z.literal('none'), z.literal('entry'), z.literal('all')]).optional(),
|
|
79
|
+
importExtension: importExtensionSchema.optional().default('.js'),
|
|
80
|
+
includePhantomTypeParameters: z.boolean().optional().default(false),
|
|
34
81
|
});
|
|
35
82
|
|
|
36
83
|
export type PackageConfig = z.infer<typeof packageConfigSchema>;
|
|
37
84
|
export type HaneulCodegenConfig = z.input<typeof configSchema>;
|
|
38
|
-
export type
|
|
85
|
+
export type ParsedSuiCodegenConfig = z.infer<typeof configSchema>;
|
|
39
86
|
|
|
40
|
-
export async function loadConfig(): Promise<
|
|
87
|
+
export async function loadConfig(): Promise<ParsedSuiCodegenConfig> {
|
|
41
88
|
const config = await cosmiconfig('haneul-codegen').search();
|
|
42
89
|
|
|
43
90
|
if (!config) {
|
|
@@ -46,7 +93,8 @@ export async function loadConfig(): Promise<ParsedHaneulCodegenConfig> {
|
|
|
46
93
|
packages: [],
|
|
47
94
|
prune: true,
|
|
48
95
|
generateSummaries: true,
|
|
49
|
-
|
|
96
|
+
importExtension: '.js',
|
|
97
|
+
includePhantomTypeParameters: false,
|
|
50
98
|
};
|
|
51
99
|
}
|
|
52
100
|
|
package/src/file-builder.ts
CHANGED
|
@@ -13,12 +13,25 @@ export class FileBuilder {
|
|
|
13
13
|
starImports: Map<string, string> = new Map();
|
|
14
14
|
protected reservedNames: Set<string> = new Set();
|
|
15
15
|
|
|
16
|
-
addImport(module: string, name: string) {
|
|
16
|
+
addImport(module: string, name: string): string {
|
|
17
17
|
if (!this.imports.has(module)) {
|
|
18
18
|
this.imports.set(module, new Set());
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const isTypeImport = name.startsWith('type ');
|
|
22
|
+
const baseName = isTypeImport ? name.slice(5) : name;
|
|
23
|
+
|
|
24
|
+
if (this.reservedNames.has(baseName)) {
|
|
25
|
+
const alias = this.getUnusedName(baseName);
|
|
26
|
+
const aliasedImport = isTypeImport
|
|
27
|
+
? `type ${baseName} as ${alias}`
|
|
28
|
+
: `${baseName} as ${alias}`;
|
|
29
|
+
this.imports.get(module)!.add(aliasedImport);
|
|
30
|
+
return alias;
|
|
31
|
+
}
|
|
32
|
+
|
|
21
33
|
this.imports.get(module)!.add(name);
|
|
34
|
+
return baseName;
|
|
22
35
|
}
|
|
23
36
|
|
|
24
37
|
addStarImport(module: string, name: string) {
|
package/src/generate-utils.ts
CHANGED
|
@@ -2,16 +2,36 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
export const utilsContent = /* ts */ `
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
bcs,
|
|
7
|
+
BcsType,
|
|
8
|
+
TypeTag,
|
|
9
|
+
TypeTagSerializer,
|
|
10
|
+
BcsStruct,
|
|
11
|
+
BcsEnum,
|
|
12
|
+
BcsTuple,
|
|
13
|
+
} from '@haneullabs/haneul/bcs';
|
|
6
14
|
import { normalizeHaneulAddress } from '@haneullabs/haneul/utils';
|
|
7
15
|
import { TransactionArgument, isArgument } from '@haneullabs/haneul/transactions';
|
|
16
|
+
import { ClientWithCoreApi, HaneulClientTypes } from '@haneullabs/haneul/client';
|
|
8
17
|
|
|
9
18
|
const MOVE_STDLIB_ADDRESS = normalizeHaneulAddress('0x1');
|
|
10
19
|
const HANEUL_FRAMEWORK_ADDRESS = normalizeHaneulAddress('0x2');
|
|
11
|
-
const HANEUL_SYSTEM_ADDRESS = normalizeHaneulAddress('0x3');
|
|
12
20
|
|
|
13
21
|
export type RawTransactionArgument<T> = T | TransactionArgument;
|
|
14
22
|
|
|
23
|
+
export interface GetOptions<
|
|
24
|
+
Include extends Omit<HaneulClientTypes.ObjectInclude, 'content'> = {},
|
|
25
|
+
> extends HaneulClientTypes.GetObjectOptions<Include> {
|
|
26
|
+
client: ClientWithCoreApi;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface GetManyOptions<
|
|
30
|
+
Include extends Omit<HaneulClientTypes.ObjectInclude, 'content'> = {},
|
|
31
|
+
> extends HaneulClientTypes.GetObjectsOptions<Include> {
|
|
32
|
+
client: ClientWithCoreApi;
|
|
33
|
+
}
|
|
34
|
+
|
|
15
35
|
export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null {
|
|
16
36
|
const parsedTag = typeof typeTag === 'string' ? TypeTagSerializer.parseFromStr(typeTag) : typeTag;
|
|
17
37
|
|
|
@@ -36,7 +56,7 @@ export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null
|
|
|
36
56
|
return type ? bcs.vector(type) : null;
|
|
37
57
|
} else if ('struct' in parsedTag) {
|
|
38
58
|
const structTag = parsedTag.struct;
|
|
39
|
-
const pkg = normalizeHaneulAddress(
|
|
59
|
+
const pkg = normalizeHaneulAddress(structTag.address);
|
|
40
60
|
|
|
41
61
|
if (pkg === MOVE_STDLIB_ADDRESS) {
|
|
42
62
|
if (
|
|
@@ -47,12 +67,16 @@ export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null
|
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
if (structTag.module === 'option' && structTag.name === 'Option') {
|
|
50
|
-
const type = getPureBcsSchema(structTag.typeParams[0]
|
|
70
|
+
const type = getPureBcsSchema(structTag.typeParams[0]);
|
|
51
71
|
return type ? bcs.option(type) : null;
|
|
52
72
|
}
|
|
53
73
|
}
|
|
54
74
|
|
|
55
|
-
if (
|
|
75
|
+
if (
|
|
76
|
+
pkg === HANEUL_FRAMEWORK_ADDRESS &&
|
|
77
|
+
structTag.module === 'object' &&
|
|
78
|
+
(structTag.name === 'ID' || structTag.name === 'UID')
|
|
79
|
+
) {
|
|
56
80
|
return bcs.Address;
|
|
57
81
|
}
|
|
58
82
|
}
|
|
@@ -60,7 +84,11 @@ export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null
|
|
|
60
84
|
return null;
|
|
61
85
|
}
|
|
62
86
|
|
|
63
|
-
export function normalizeMoveArguments(
|
|
87
|
+
export function normalizeMoveArguments(
|
|
88
|
+
args: unknown[] | object,
|
|
89
|
+
argTypes: readonly (string | null)[],
|
|
90
|
+
parameterNames?: string[],
|
|
91
|
+
) {
|
|
64
92
|
const argLen = Array.isArray(args) ? args.length : Object.keys(args).length;
|
|
65
93
|
if (parameterNames && argLen !== parameterNames.length) {
|
|
66
94
|
throw new Error(
|
|
@@ -72,30 +100,32 @@ export function normalizeMoveArguments(args: unknown[] | object, argTypes: strin
|
|
|
72
100
|
|
|
73
101
|
let index = 0;
|
|
74
102
|
for (const [i, argType] of argTypes.entries()) {
|
|
75
|
-
if (argType ===
|
|
76
|
-
normalizedArgs.push((tx) => tx.object.
|
|
103
|
+
if (argType === '0x2::clock::Clock') {
|
|
104
|
+
normalizedArgs.push((tx) => tx.object.clock());
|
|
77
105
|
continue;
|
|
78
106
|
}
|
|
79
107
|
|
|
80
|
-
if (argType ===
|
|
108
|
+
if (argType === '0x2::random::Random') {
|
|
81
109
|
normalizedArgs.push((tx) => tx.object.random());
|
|
82
110
|
continue;
|
|
83
111
|
}
|
|
84
112
|
|
|
85
|
-
if (argType ===
|
|
86
|
-
normalizedArgs.push((tx) => tx.object.
|
|
113
|
+
if (argType === '0x2::deny_list::DenyList') {
|
|
114
|
+
normalizedArgs.push((tx) => tx.object.denyList());
|
|
87
115
|
continue;
|
|
88
116
|
}
|
|
89
117
|
|
|
90
|
-
if (argType ===
|
|
118
|
+
if (argType === '0x3::haneul_system::HaneulSystemState') {
|
|
91
119
|
normalizedArgs.push((tx) => tx.object.system());
|
|
92
120
|
continue;
|
|
93
121
|
}
|
|
94
122
|
|
|
95
|
-
let arg
|
|
123
|
+
let arg;
|
|
96
124
|
if (Array.isArray(args)) {
|
|
97
125
|
if (index >= args.length) {
|
|
98
|
-
throw new Error(
|
|
126
|
+
throw new Error(
|
|
127
|
+
\`Invalid number of arguments, expected at least \${index + 1}, got \${args.length}\`,
|
|
128
|
+
);
|
|
99
129
|
}
|
|
100
130
|
arg = args[index];
|
|
101
131
|
} else {
|
|
@@ -117,8 +147,8 @@ export function normalizeMoveArguments(args: unknown[] | object, argTypes: strin
|
|
|
117
147
|
continue;
|
|
118
148
|
}
|
|
119
149
|
|
|
120
|
-
const type = argTypes[i]
|
|
121
|
-
const bcsType = getPureBcsSchema(type);
|
|
150
|
+
const type = argTypes[i];
|
|
151
|
+
const bcsType = type === null ? null : getPureBcsSchema(type);
|
|
122
152
|
|
|
123
153
|
if (bcsType) {
|
|
124
154
|
const bytes = bcsType.serialize(arg as never);
|
|
@@ -138,7 +168,47 @@ export function normalizeMoveArguments(args: unknown[] | object, argTypes: strin
|
|
|
138
168
|
export class MoveStruct<
|
|
139
169
|
T extends Record<string, BcsType<any>>,
|
|
140
170
|
const Name extends string = string,
|
|
141
|
-
> extends BcsStruct<T, Name> {
|
|
171
|
+
> extends BcsStruct<T, Name> {
|
|
172
|
+
async get<Include extends Omit<HaneulClientTypes.ObjectInclude, 'content' | 'json'> = {}>({
|
|
173
|
+
objectId,
|
|
174
|
+
...options
|
|
175
|
+
}: GetOptions<Include>): Promise<
|
|
176
|
+
HaneulClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }
|
|
177
|
+
> {
|
|
178
|
+
const [res] = await this.getMany<Include>({
|
|
179
|
+
...options,
|
|
180
|
+
objectIds: [objectId],
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return res;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async getMany<Include extends Omit<HaneulClientTypes.ObjectInclude, 'content' | 'json'> = {}>({
|
|
187
|
+
client,
|
|
188
|
+
...options
|
|
189
|
+
}: GetManyOptions<Include>): Promise<
|
|
190
|
+
Array<HaneulClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }>
|
|
191
|
+
> {
|
|
192
|
+
const response = (await client.core.getObjects({
|
|
193
|
+
...options,
|
|
194
|
+
include: {
|
|
195
|
+
...options.include,
|
|
196
|
+
content: true,
|
|
197
|
+
},
|
|
198
|
+
})) as HaneulClientTypes.GetObjectsResponse<Include & { content: true }>;
|
|
199
|
+
|
|
200
|
+
return response.objects.map((obj) => {
|
|
201
|
+
if (obj instanceof Error) {
|
|
202
|
+
throw obj;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
...obj,
|
|
207
|
+
json: this.parse(obj.content),
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
142
212
|
|
|
143
213
|
export class MoveEnum<
|
|
144
214
|
T extends Record<string, BcsType<any> | null>,
|
|
@@ -146,7 +216,7 @@ export class MoveEnum<
|
|
|
146
216
|
> extends BcsEnum<T, Name> {}
|
|
147
217
|
|
|
148
218
|
export class MoveTuple<
|
|
149
|
-
T extends readonly BcsType<any>[],
|
|
219
|
+
const T extends readonly BcsType<any>[],
|
|
150
220
|
const Name extends string,
|
|
151
221
|
> extends BcsTuple<T, Name> {}
|
|
152
222
|
|
package/src/index.ts
CHANGED
|
@@ -1,40 +1,65 @@
|
|
|
1
1
|
// Copyright (c) Mysten Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
5
5
|
import { basename, join } from 'node:path';
|
|
6
6
|
import { MoveModuleBuilder } from './move-module-builder.js';
|
|
7
7
|
import { existsSync, statSync } from 'node:fs';
|
|
8
8
|
import { utilsContent } from './generate-utils.js';
|
|
9
9
|
import { parse } from 'toml';
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
FunctionsOption,
|
|
12
|
+
GenerateBase,
|
|
13
|
+
ImportExtension,
|
|
14
|
+
PackageConfig,
|
|
15
|
+
PackageGenerate,
|
|
16
|
+
TypesOption,
|
|
17
|
+
} from './config.js';
|
|
11
18
|
export { type HaneulCodegenConfig } from './config.js';
|
|
12
19
|
|
|
13
20
|
export async function generateFromPackageSummary({
|
|
14
21
|
package: pkg,
|
|
15
22
|
prune,
|
|
16
23
|
outputDir,
|
|
17
|
-
|
|
24
|
+
globalGenerate,
|
|
25
|
+
importExtension = '.js',
|
|
26
|
+
includePhantomTypeParameters = false,
|
|
18
27
|
}: {
|
|
19
28
|
package: PackageConfig;
|
|
20
29
|
prune: boolean;
|
|
21
30
|
outputDir: string;
|
|
22
|
-
|
|
31
|
+
globalGenerate?: GenerateBase;
|
|
32
|
+
importExtension?: ImportExtension;
|
|
33
|
+
includePhantomTypeParameters?: boolean;
|
|
23
34
|
}) {
|
|
24
35
|
if (!pkg.path) {
|
|
25
|
-
throw new Error(`
|
|
36
|
+
throw new Error(`Package path is required (got ${pkg.package})`);
|
|
26
37
|
}
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
// Check for on-chain package summary (directly in path) or local package summary (in package_summaries subdirectory)
|
|
40
|
+
const localSummaryDir = join(pkg.path, 'package_summaries');
|
|
41
|
+
const isOnChainPackage = existsSync(join(pkg.path, 'root_package_metadata.json'));
|
|
42
|
+
const summaryDir = isOnChainPackage ? pkg.path : localSummaryDir;
|
|
29
43
|
|
|
30
|
-
if (!existsSync(summaryDir)) {
|
|
44
|
+
if (!existsSync(summaryDir) || !existsSync(join(summaryDir, 'address_mapping.json'))) {
|
|
31
45
|
throw new Error(`Package summary directory not found: ${summaryDir}`);
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
let packageName = pkg.packageName!;
|
|
49
|
+
let mainPackageAddress: string | undefined;
|
|
35
50
|
const mvrNameOrAddress = pkg.package;
|
|
36
51
|
|
|
37
|
-
if (
|
|
52
|
+
if (isOnChainPackage) {
|
|
53
|
+
// For on-chain packages, get the main package address from root_package_metadata.json
|
|
54
|
+
const metadata = JSON.parse(
|
|
55
|
+
await readFile(join(pkg.path, 'root_package_metadata.json'), 'utf-8'),
|
|
56
|
+
);
|
|
57
|
+
mainPackageAddress = metadata.root_package_id;
|
|
58
|
+
// Use the package name provided or fall back to the full address
|
|
59
|
+
if (!packageName) {
|
|
60
|
+
packageName = mainPackageAddress!;
|
|
61
|
+
}
|
|
62
|
+
} else if (!pkg.packageName) {
|
|
38
63
|
try {
|
|
39
64
|
const packageToml = await readFile(join(pkg.path, 'Move.toml'), 'utf-8');
|
|
40
65
|
packageName = parse(packageToml).package.name.toLowerCase();
|
|
@@ -48,10 +73,6 @@ export async function generateFromPackageSummary({
|
|
|
48
73
|
}
|
|
49
74
|
}
|
|
50
75
|
|
|
51
|
-
if (!existsSync(summaryDir)) {
|
|
52
|
-
throw new Error(`Package summary directory not found: ${summaryDir}`);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
76
|
const addressMappings: Record<string, string> = JSON.parse(
|
|
56
77
|
await readFile(join(summaryDir, 'address_mapping.json'), 'utf-8'),
|
|
57
78
|
);
|
|
@@ -59,21 +80,35 @@ export async function generateFromPackageSummary({
|
|
|
59
80
|
const packages = (await readdir(summaryDir)).filter((file) =>
|
|
60
81
|
statSync(join(summaryDir, file)).isDirectory(),
|
|
61
82
|
);
|
|
83
|
+
|
|
84
|
+
// For on-chain packages, the main package is identified by the root_package_id
|
|
85
|
+
// For local packages, it's identified by the packageName
|
|
86
|
+
const isMainPackage = (pkgDir: string) => {
|
|
87
|
+
if (isOnChainPackage) {
|
|
88
|
+
return pkgDir === mainPackageAddress;
|
|
89
|
+
}
|
|
90
|
+
return pkgDir === packageName;
|
|
91
|
+
};
|
|
92
|
+
|
|
62
93
|
const modules = (
|
|
63
94
|
await Promise.all(
|
|
64
|
-
packages.map(async (
|
|
65
|
-
const
|
|
95
|
+
packages.map(async (pkgDir) => {
|
|
96
|
+
const moduleFiles = await readdir(join(summaryDir, pkgDir));
|
|
66
97
|
return Promise.all(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
moduleFiles
|
|
99
|
+
.filter((f) => f.endsWith('.json'))
|
|
100
|
+
.map(async (mod) => ({
|
|
101
|
+
package: pkgDir,
|
|
102
|
+
isMainPackage: isMainPackage(pkgDir),
|
|
103
|
+
module: basename(mod, '.json'),
|
|
104
|
+
builder: await MoveModuleBuilder.fromSummaryFile(
|
|
105
|
+
join(summaryDir, pkgDir, mod),
|
|
106
|
+
addressMappings,
|
|
107
|
+
isMainPackage(pkgDir) ? mvrNameOrAddress : undefined,
|
|
108
|
+
importExtension,
|
|
109
|
+
includePhantomTypeParameters,
|
|
110
|
+
),
|
|
111
|
+
})),
|
|
77
112
|
);
|
|
78
113
|
}),
|
|
79
114
|
)
|
|
@@ -83,15 +118,40 @@ export async function generateFromPackageSummary({
|
|
|
83
118
|
modules.map((mod) => [`${mod.package}::${mod.module}`, mod.builder]),
|
|
84
119
|
);
|
|
85
120
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
121
|
+
const packageGenerate: PackageGenerate | undefined = 'generate' in pkg ? pkg.generate : undefined;
|
|
122
|
+
const pkgModules = packageGenerate?.modules;
|
|
123
|
+
const pkgTypes: TypesOption = packageGenerate?.types ?? globalGenerate?.types ?? true;
|
|
124
|
+
const pkgFunctions: FunctionsOption =
|
|
125
|
+
packageGenerate?.functions ?? globalGenerate?.functions ?? true;
|
|
126
|
+
|
|
127
|
+
for (const mod of modules) {
|
|
128
|
+
if (!mod.isMainPackage && prune) {
|
|
129
|
+
continue;
|
|
90
130
|
}
|
|
91
|
-
|
|
131
|
+
|
|
132
|
+
const moduleGenerate = !pkgModules
|
|
133
|
+
? true
|
|
134
|
+
: Array.isArray(pkgModules)
|
|
135
|
+
? pkgModules.includes(mod.module) || null
|
|
136
|
+
: mod.module in pkgModules
|
|
137
|
+
? pkgModules[mod.module]
|
|
138
|
+
: null;
|
|
139
|
+
|
|
140
|
+
if (!moduleGenerate) continue;
|
|
141
|
+
|
|
142
|
+
const types = moduleGenerate === true ? pkgTypes : (moduleGenerate.types ?? false);
|
|
143
|
+
const functions = moduleGenerate === true ? pkgFunctions : (moduleGenerate.functions ?? false);
|
|
144
|
+
|
|
145
|
+
mod.builder.includeTypes(moduleBuilders, types);
|
|
146
|
+
mod.builder.includeFunctions(functions);
|
|
147
|
+
}
|
|
92
148
|
|
|
93
149
|
await generateUtils({ outputDir });
|
|
94
150
|
|
|
151
|
+
// Clean the package output directory to remove stale files from previous runs
|
|
152
|
+
const packageOutputDir = join(outputDir, packageName);
|
|
153
|
+
await rm(packageOutputDir, { recursive: true, force: true });
|
|
154
|
+
|
|
95
155
|
await Promise.all(
|
|
96
156
|
modules.map(async (mod) => {
|
|
97
157
|
if ((mod.isMainPackage || !prune) && mod.builder.hasTypesOrFunctions()) {
|