@latticexyz/cli 1.41.1-alpha.41 → 1.42.0
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/dist/chunk-4STWSICF.js +26139 -0
- package/dist/chunk-6V563IAZ.js +283 -0
- package/dist/chunk-7KQJTK2K.js +3842 -0
- package/dist/{chunk-ATAWDHWC.js → chunk-FPG73MVN.js} +5 -1
- package/dist/{chunk-O6HOO6WA.js → chunk-L4YLJHLJ.js} +1 -9
- package/dist/{chunk-J4DJQNIC.js → chunk-SKNB74MT.js} +129 -568
- package/dist/chunk-VQTZJIFF.js +353 -0
- package/dist/chunk-WZFXLDPK.js +761 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.js +0 -21
- package/dist/mud.d.ts +1 -1
- package/dist/mud.js +326 -4452
- package/dist/mud2.d.ts +1 -0
- package/dist/mud2.js +25 -0
- package/dist/render-solidity/index.d.ts +171 -0
- package/dist/render-solidity/index.js +49 -0
- package/dist/render-ts/index.d.ts +26 -0
- package/dist/render-ts/index.js +14 -0
- package/dist/utils/deprecated/index.js +3 -3
- package/dist/utils/index.d.ts +13 -18
- package/dist/utils/index.js +14 -16
- package/package.json +21 -21
- package/src/commands/deploy-v2.ts +80 -64
- package/src/commands/deprecated/index.ts +22 -0
- package/src/commands/deprecated/test.ts +1 -1
- package/src/commands/gas-report.ts +54 -55
- package/src/commands/index.ts +6 -17
- package/src/commands/set-version.ts +172 -0
- package/src/commands/tablegen.ts +5 -5
- package/src/commands/test-v2.ts +71 -0
- package/src/commands/tsgen.ts +33 -0
- package/src/commands/worldgen.ts +5 -4
- package/src/contracts/BulkUpload.sol +13 -20
- package/src/contracts/Deploy.sol +3 -3
- package/src/contracts/LibDeploy.sol +1 -1
- package/src/contracts/LibDeployStub.sol +1 -1
- package/src/index.ts +1 -15
- package/src/mud.ts +4 -3
- package/src/mud2.ts +29 -0
- package/src/render-solidity/common.ts +4 -4
- package/src/render-solidity/field.ts +25 -2
- package/src/render-solidity/record.ts +14 -10
- package/src/render-solidity/renderSystemInterface.ts +4 -4
- package/src/render-solidity/renderTableIndex.ts +15 -0
- package/src/render-solidity/renderTypesFromConfig.ts +1 -1
- package/src/render-solidity/tableOptions.ts +2 -2
- package/src/render-solidity/tablegen.ts +15 -13
- package/src/render-solidity/types.ts +2 -1
- package/src/render-solidity/userType.ts +1 -2
- package/src/render-solidity/worldgen.ts +8 -9
- package/src/render-ts/index.ts +5 -0
- package/src/render-ts/recsV1TableOptions.ts +39 -0
- package/src/render-ts/renderRecsV1Tables.ts +31 -0
- package/src/render-ts/schemaTypesToRecsTypeStrings.ts +202 -0
- package/src/render-ts/tsgen.ts +12 -0
- package/src/render-ts/types.ts +13 -0
- package/src/utils/contractToInterface.ts +5 -3
- package/src/utils/deploy-v2.ts +90 -84
- package/src/utils/errors.ts +3 -34
- package/src/utils/format.ts +6 -0
- package/src/utils/formatAndWrite.ts +11 -2
- package/src/utils/foundry.ts +9 -0
- package/src/utils/index.ts +1 -0
- package/dist/chunk-O57QENJ6.js +0 -23039
- package/dist/chunk-SLIMIO4Z.js +0 -14358
- package/dist/config/index.d.ts +0 -763
- package/dist/config/index.js +0 -83
- package/src/config/commonSchemas.ts +0 -34
- package/src/config/dynamicResolution.ts +0 -49
- package/src/config/index.ts +0 -24
- package/src/config/loadConfig.ts +0 -39
- package/src/config/loadStoreConfig.ts +0 -18
- package/src/config/parseStoreConfig.test-d.ts +0 -40
- package/src/config/parseStoreConfig.ts +0 -314
- package/src/config/validation.ts +0 -163
- package/src/config/world/index.ts +0 -4
- package/src/config/world/loadWorldConfig.test-d.ts +0 -11
- package/src/config/world/loadWorldConfig.ts +0 -26
- package/src/config/world/parseWorldConfig.ts +0 -55
- package/src/config/world/resolveWorldConfig.ts +0 -80
- package/src/config/world/userTypes.ts +0 -72
- package/src/utils/typeUtils.ts +0 -17
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { CommandModule } from "yargs";
|
|
2
|
+
import { deployHandler, DeployOptions } from "./deploy-v2.js";
|
|
3
|
+
import { yDeployOptions } from "./deploy-v2.js";
|
|
4
|
+
import { anvil, forge, getRpcUrl, getTestDirectory } from "../utils/foundry.js";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { rmSync, writeFileSync } from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
|
|
9
|
+
type Options = DeployOptions & { port?: number; worldAddress?: string; forgeOptions?: string };
|
|
10
|
+
|
|
11
|
+
const WORLD_ADDRESS_FILE = ".mudtest";
|
|
12
|
+
|
|
13
|
+
const commandModule: CommandModule<Options, Options> = {
|
|
14
|
+
command: "test-v2",
|
|
15
|
+
|
|
16
|
+
describe: "Run tests in MUD v2 contracts",
|
|
17
|
+
|
|
18
|
+
builder(yargs) {
|
|
19
|
+
return yargs.options({
|
|
20
|
+
...yDeployOptions,
|
|
21
|
+
port: { type: "number", description: "Port to run internal node for fork testing on", default: 4242 },
|
|
22
|
+
worldAddress: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description:
|
|
25
|
+
"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing.",
|
|
26
|
+
},
|
|
27
|
+
forgeOptions: { type: "string", description: "Options to pass to forge test" },
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
async handler(args) {
|
|
32
|
+
// Start an internal anvil process if no world address is provided
|
|
33
|
+
if (!args.worldAddress) {
|
|
34
|
+
const anvilArgs = ["--block-base-fee-per-gas", "0", "--port", String(args.port)];
|
|
35
|
+
anvil(anvilArgs);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const forkRpc = args.worldAddress ? await getRpcUrl(args.profile) : `http://127.0.0.1:${args.port}`;
|
|
39
|
+
|
|
40
|
+
const worldAddress =
|
|
41
|
+
args.worldAddress ??
|
|
42
|
+
(
|
|
43
|
+
await deployHandler({
|
|
44
|
+
...args,
|
|
45
|
+
saveDeployment: false,
|
|
46
|
+
rpc: forkRpc,
|
|
47
|
+
})
|
|
48
|
+
).worldAddress;
|
|
49
|
+
|
|
50
|
+
console.log(chalk.blue("World address", worldAddress));
|
|
51
|
+
|
|
52
|
+
// Create a temporary file to pass the world address to the tests
|
|
53
|
+
writeFileSync(WORLD_ADDRESS_FILE, worldAddress);
|
|
54
|
+
|
|
55
|
+
const userOptions = args.forgeOptions?.replaceAll("\\", "").split(" ") ?? [];
|
|
56
|
+
try {
|
|
57
|
+
const testResult = await forge(["test", "--fork-url", forkRpc, ...userOptions], {
|
|
58
|
+
profile: args.profile,
|
|
59
|
+
});
|
|
60
|
+
console.log(testResult);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error(e);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
rmSync(WORLD_ADDRESS_FILE);
|
|
66
|
+
|
|
67
|
+
process.exit(0);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default commandModule;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CommandModule } from "yargs";
|
|
2
|
+
import { loadStoreConfig } from "@latticexyz/config";
|
|
3
|
+
import { tsgen } from "../render-ts/tsgen.js";
|
|
4
|
+
|
|
5
|
+
type Options = {
|
|
6
|
+
configPath: string;
|
|
7
|
+
out: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const commandModule: CommandModule<Options, Options> = {
|
|
11
|
+
command: "tsgen",
|
|
12
|
+
|
|
13
|
+
describe: "Autogenerate MUD typescript definitions based on the config file",
|
|
14
|
+
|
|
15
|
+
builder(yargs) {
|
|
16
|
+
return yargs.options({
|
|
17
|
+
configPath: { type: "string", demandOption: true, desc: "Path to the config file" },
|
|
18
|
+
out: { type: "string", demandOption: true, desc: "Directory to output MUD typescript definition files" },
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
async handler(args) {
|
|
23
|
+
const { configPath, out } = args;
|
|
24
|
+
|
|
25
|
+
const config = await loadStoreConfig(configPath);
|
|
26
|
+
|
|
27
|
+
await tsgen(config, out);
|
|
28
|
+
|
|
29
|
+
process.exit(0);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default commandModule;
|
package/src/commands/worldgen.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { CommandModule } from "yargs";
|
|
2
|
-
import { loadStoreConfig } from "
|
|
3
|
-
import { loadWorldConfig } from "../config/index.js";
|
|
2
|
+
import { loadStoreConfig, loadWorldConfig } from "@latticexyz/config";
|
|
4
3
|
import { getSrcDirectory } from "../utils/foundry.js";
|
|
5
4
|
import glob from "glob";
|
|
6
5
|
import path, { basename } from "path";
|
|
@@ -42,11 +41,13 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
42
41
|
const storeConfig = await loadStoreConfig(configPath);
|
|
43
42
|
const mudConfig = { ...worldConfig, ...storeConfig };
|
|
44
43
|
|
|
44
|
+
const outputBaseDirectory = path.join(srcDir, mudConfig.codegenDirectory);
|
|
45
|
+
|
|
45
46
|
// clear the worldgen directory
|
|
46
|
-
if (clean) rmSync(path.join(
|
|
47
|
+
if (clean) rmSync(path.join(outputBaseDirectory, mudConfig.worldgenDirectory), { recursive: true, force: true });
|
|
47
48
|
|
|
48
49
|
// generate new interfaces
|
|
49
|
-
await worldgen(mudConfig, existingContracts,
|
|
50
|
+
await worldgen(mudConfig, existingContracts, outputBaseDirectory);
|
|
50
51
|
|
|
51
52
|
process.exit(0);
|
|
52
53
|
},
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity >=0.8.0;
|
|
3
3
|
|
|
4
|
-
import {Script} from "forge-std/Script.sol";
|
|
5
|
-
import {console} from "forge-std/console.sol";
|
|
4
|
+
import { Script } from "forge-std/Script.sol";
|
|
5
|
+
import { console } from "forge-std/console.sol";
|
|
6
6
|
|
|
7
|
-
import {BulkSetStateSystem, ID as BulkSetStateSystemID, ECSEvent} from "std-contracts/systems/BulkSetStateSystem.sol";
|
|
8
|
-
import {World} from "solecs/World.sol";
|
|
9
|
-
import {System} from "solecs/System.sol";
|
|
10
|
-
import {getAddressById} from "solecs/utils.sol";
|
|
11
|
-
import {Set} from "solecs/Set.sol";
|
|
7
|
+
import { BulkSetStateSystem, ID as BulkSetStateSystemID, ECSEvent } from "std-contracts/systems/BulkSetStateSystem.sol";
|
|
8
|
+
import { World } from "solecs/World.sol";
|
|
9
|
+
import { System } from "solecs/System.sol";
|
|
10
|
+
import { getAddressById } from "solecs/utils.sol";
|
|
11
|
+
import { Set } from "solecs/Set.sol";
|
|
12
12
|
|
|
13
13
|
struct ParsedState {
|
|
14
14
|
string[] componentIds;
|
|
@@ -33,11 +33,7 @@ struct State {
|
|
|
33
33
|
* forge script --sig "run(string, address)" --rpc-url http://localhost:8545 src/contracts/BulkUpload.sol:BulkUpload path/to/ecs-map-test.json <WORLD_ADDRESS>
|
|
34
34
|
*/
|
|
35
35
|
contract BulkUpload is Script {
|
|
36
|
-
function run(
|
|
37
|
-
string memory path,
|
|
38
|
-
address worldAddress,
|
|
39
|
-
uint256 eventsPerTx
|
|
40
|
-
) public {
|
|
36
|
+
function run(string memory path, address worldAddress, uint256 eventsPerTx) public {
|
|
41
37
|
vmSafe.startBroadcast();
|
|
42
38
|
|
|
43
39
|
// Read JSON
|
|
@@ -108,9 +104,10 @@ contract BulkUpload is Script {
|
|
|
108
104
|
}
|
|
109
105
|
}
|
|
110
106
|
|
|
111
|
-
function transformEventsToOnlyUseNeededEntities(
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
function transformEventsToOnlyUseNeededEntities(
|
|
108
|
+
uint256[] memory entities,
|
|
109
|
+
ECSEvent[] memory events
|
|
110
|
+
) returns (uint256[] memory, ECSEvent[] memory) {
|
|
114
111
|
Set uniqueEntityIndices = new Set();
|
|
115
112
|
|
|
116
113
|
// Find unique entity indices
|
|
@@ -167,11 +164,7 @@ function hexToBytes(string memory s) pure returns (bytes memory) {
|
|
|
167
164
|
return r;
|
|
168
165
|
}
|
|
169
166
|
|
|
170
|
-
function substring(
|
|
171
|
-
string memory str,
|
|
172
|
-
uint256 start,
|
|
173
|
-
uint256 end
|
|
174
|
-
) pure returns (string memory) {
|
|
167
|
+
function substring(string memory str, uint256 start, uint256 end) pure returns (string memory) {
|
|
175
168
|
bytes memory strBytes = bytes(str);
|
|
176
169
|
bytes memory result = new bytes(end - start);
|
|
177
170
|
for (uint256 i = start; i < end; i++) {
|
package/src/contracts/Deploy.sol
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
pragma solidity >=0.8.0;
|
|
3
3
|
|
|
4
4
|
// Foundry
|
|
5
|
-
import {Script} from "forge-std/Script.sol";
|
|
6
|
-
import {console} from "forge-std/console.sol";
|
|
5
|
+
import { Script } from "forge-std/Script.sol";
|
|
6
|
+
import { console } from "forge-std/console.sol";
|
|
7
7
|
|
|
8
8
|
// Libraries
|
|
9
|
-
import {LibDeploy, DeployResult} from "./LibDeploy.sol";
|
|
9
|
+
import { LibDeploy, DeployResult } from "./LibDeploy.sol";
|
|
10
10
|
|
|
11
11
|
contract Deploy is Script {
|
|
12
12
|
function broadcastDeploy(
|
|
@@ -7,7 +7,7 @@ pragma solidity >=0.8.0;
|
|
|
7
7
|
// To manually generate the real LibDeploy.sol use
|
|
8
8
|
// `mud codegen-libdeploy`.
|
|
9
9
|
|
|
10
|
-
import {IWorld} from "solecs/interfaces/IWorld.sol";
|
|
10
|
+
import { IWorld } from "solecs/interfaces/IWorld.sol";
|
|
11
11
|
|
|
12
12
|
struct DeployResult {
|
|
13
13
|
IWorld world;
|
|
@@ -7,7 +7,7 @@ pragma solidity >=0.8.0;
|
|
|
7
7
|
// To manually generate the real LibDeploy.sol use
|
|
8
8
|
// `mud codegen-libdeploy`.
|
|
9
9
|
|
|
10
|
-
import {IWorld} from "solecs/interfaces/IWorld.sol";
|
|
10
|
+
import { IWorld } from "solecs/interfaces/IWorld.sol";
|
|
11
11
|
|
|
12
12
|
struct DeployResult {
|
|
13
13
|
IWorld world;
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { parseStoreConfig } from "./config/parseStoreConfig.js";
|
|
3
|
-
export { loadWorldConfig, resolveWorldConfig, parseWorldConfig } from "./config/world/index.js";
|
|
4
|
-
export { resolveTableId } from "./config/dynamicResolution.js";
|
|
5
|
-
|
|
6
|
-
export type {
|
|
7
|
-
StoreUserConfig,
|
|
8
|
-
StoreConfig,
|
|
9
|
-
WorldUserConfig,
|
|
10
|
-
ResolvedWorldConfig,
|
|
11
|
-
MUDUserConfig,
|
|
12
|
-
MUDConfig,
|
|
13
|
-
} from "./config/index.js";
|
|
14
|
-
|
|
15
|
-
export { storeConfig, mudConfig } from "./config/index.js";
|
|
1
|
+
export {};
|
package/src/mud.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import yargs from "yargs";
|
|
4
4
|
import { hideBin } from "yargs/helpers";
|
|
5
|
-
import { commands } from "./commands/index.js";
|
|
5
|
+
import { commands as v2 } from "./commands/index.js";
|
|
6
|
+
import { commands as v1 } from "./commands/deprecated/index.js";
|
|
6
7
|
import { logError } from "./utils/errors.js";
|
|
7
8
|
|
|
8
9
|
// Load .env file into process.env
|
|
@@ -14,7 +15,7 @@ yargs(hideBin(process.argv))
|
|
|
14
15
|
.scriptName("mud")
|
|
15
16
|
// Use the commands directory to scaffold
|
|
16
17
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy
|
|
17
|
-
.command(
|
|
18
|
+
.command([...v1, ...v2] as any)
|
|
18
19
|
// Enable strict mode.
|
|
19
20
|
.strict()
|
|
20
21
|
// Custom error handler
|
package/src/mud2.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import yargs from "yargs";
|
|
4
|
+
import { hideBin } from "yargs/helpers";
|
|
5
|
+
import { commands } from "./commands/index.js";
|
|
6
|
+
import { logError } from "./utils/errors.js";
|
|
7
|
+
|
|
8
|
+
// Load .env file into process.env
|
|
9
|
+
import * as dotenv from "dotenv";
|
|
10
|
+
dotenv.config();
|
|
11
|
+
|
|
12
|
+
yargs(hideBin(process.argv))
|
|
13
|
+
// Explicit name to display in help (by default it's the entry file, which may not be "mud" for e.g. ts-node)
|
|
14
|
+
.scriptName("mud")
|
|
15
|
+
// Use the commands directory to scaffold
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy
|
|
17
|
+
.command(commands as any)
|
|
18
|
+
// Enable strict mode.
|
|
19
|
+
.strict()
|
|
20
|
+
// Custom error handler
|
|
21
|
+
.fail((msg, err) => {
|
|
22
|
+
console.log("");
|
|
23
|
+
logError(err);
|
|
24
|
+
console.log("");
|
|
25
|
+
|
|
26
|
+
process.exit(1);
|
|
27
|
+
})
|
|
28
|
+
// Useful aliases.
|
|
29
|
+
.alias({ h: "help" }).argv;
|
|
@@ -27,7 +27,7 @@ export function renderCommonData({
|
|
|
27
27
|
}: Pick<RenderTableOptions, "staticResourceData" | "primaryKeys">) {
|
|
28
28
|
// static resource means static tableId as well, and no tableId arguments
|
|
29
29
|
const _tableId = staticResourceData ? "" : "_tableId";
|
|
30
|
-
const _typedTableId = staticResourceData ? "" : "
|
|
30
|
+
const _typedTableId = staticResourceData ? "" : "bytes32 _tableId";
|
|
31
31
|
|
|
32
32
|
const _keyArgs = renderArguments(primaryKeys.map(({ name }) => name));
|
|
33
33
|
const _typedKeyArgs = renderArguments(primaryKeys.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
|
|
@@ -100,11 +100,11 @@ export function renderWithStore(
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export function renderTableId(staticResourceData: StaticResourceData) {
|
|
103
|
-
const hardcodedTableId = `
|
|
103
|
+
const hardcodedTableId = `bytes32(abi.encodePacked(bytes16("${staticResourceData.namespace}"), bytes16("${staticResourceData.name}")))`;
|
|
104
104
|
|
|
105
105
|
const tableIdDefinition = `
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
bytes32 constant _tableId = ${hardcodedTableId};
|
|
107
|
+
bytes32 constant ${staticResourceData.tableIdName} = _tableId;
|
|
108
108
|
`;
|
|
109
109
|
return {
|
|
110
110
|
hardcodedTableId,
|
|
@@ -41,8 +41,6 @@ export function renderFieldMethods(options: RenderTableOptions) {
|
|
|
41
41
|
`
|
|
42
42
|
);
|
|
43
43
|
|
|
44
|
-
// TODO: this is super inefficient right now, need to add support for pushing to arrays to the store core library to avoid reading/writing the entire array
|
|
45
|
-
// (see https://github.com/latticexyz/mud/issues/438)
|
|
46
44
|
if (field.isDynamic) {
|
|
47
45
|
const portionData = fieldPortionData(field);
|
|
48
46
|
|
|
@@ -61,6 +59,29 @@ export function renderFieldMethods(options: RenderTableOptions) {
|
|
|
61
59
|
}
|
|
62
60
|
`
|
|
63
61
|
);
|
|
62
|
+
|
|
63
|
+
result += renderWithStore(
|
|
64
|
+
storeArgument,
|
|
65
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
66
|
+
/** Update ${portionData.title} of ${field.name}${_commentSuffix} at \`_index\` */
|
|
67
|
+
function update${field.methodNameSuffix}(${renderArguments([
|
|
68
|
+
_typedStore,
|
|
69
|
+
_typedTableId,
|
|
70
|
+
_typedKeyArgs,
|
|
71
|
+
"uint256 _index",
|
|
72
|
+
`${portionData.typeWithLocation} ${portionData.name}`,
|
|
73
|
+
])}) internal {
|
|
74
|
+
${_primaryKeysDefinition}
|
|
75
|
+
${_store}.updateInField(
|
|
76
|
+
_tableId,
|
|
77
|
+
_primaryKeys,
|
|
78
|
+
${index},
|
|
79
|
+
_index * ${portionData.elementLength},
|
|
80
|
+
${portionData.encoded}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
`
|
|
84
|
+
);
|
|
64
85
|
}
|
|
65
86
|
}
|
|
66
87
|
return result;
|
|
@@ -109,6 +130,7 @@ function fieldPortionData(field: RenderTableField) {
|
|
|
109
130
|
name: "_element",
|
|
110
131
|
encoded: renderEncodeField({ ...field.arrayElement, arrayElement: undefined, name, methodNameSuffix }),
|
|
111
132
|
title: "an element",
|
|
133
|
+
elementLength: field.arrayElement.staticByteLength,
|
|
112
134
|
};
|
|
113
135
|
} else {
|
|
114
136
|
const name = "_slice";
|
|
@@ -117,6 +139,7 @@ function fieldPortionData(field: RenderTableField) {
|
|
|
117
139
|
name,
|
|
118
140
|
encoded: renderEncodeField({ ...field, name, methodNameSuffix }),
|
|
119
141
|
title: "a slice",
|
|
142
|
+
elementLength: 1,
|
|
120
143
|
};
|
|
121
144
|
}
|
|
122
145
|
}
|
|
@@ -99,16 +99,20 @@ function renderDecodeFunction({ structName, fields, staticFields, dynamicFields
|
|
|
99
99
|
${fieldNamePrefix}${field.name} = ${renderDecodeValueType(field, staticOffsets[index])};
|
|
100
100
|
`
|
|
101
101
|
)}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
// Store trims the blob if dynamic fields are all empty
|
|
103
|
+
if (_blob.length > ${totalStaticLength}) {
|
|
104
|
+
uint256 _start;
|
|
105
|
+
// skip static data length + dynamic lengths word
|
|
106
|
+
uint256 _end = ${totalStaticLength + 32};
|
|
107
|
+
${renderList(
|
|
108
|
+
dynamicFields,
|
|
109
|
+
(field, index) => `
|
|
110
|
+
_start = _end;
|
|
111
|
+
_end += _encodedLengths.atIndex(${index});
|
|
112
|
+
${fieldNamePrefix}${field.name} = ${renderDecodeDynamicFieldPartial(field)};
|
|
113
|
+
`
|
|
114
|
+
)}
|
|
115
|
+
}
|
|
112
116
|
}
|
|
113
117
|
`;
|
|
114
118
|
} else {
|
|
@@ -11,10 +11,10 @@ ${renderImports(imports)}
|
|
|
11
11
|
interface ${name} {
|
|
12
12
|
${renderList(
|
|
13
13
|
functions,
|
|
14
|
-
({ name, parameters, returnParameters }) => `
|
|
15
|
-
function ${functionPrefix}${name}(
|
|
16
|
-
|
|
17
|
-
)};
|
|
14
|
+
({ name, parameters, stateMutability, returnParameters }) => `
|
|
15
|
+
function ${functionPrefix}${name}(
|
|
16
|
+
${renderArguments(parameters)}
|
|
17
|
+
) external ${stateMutability} ${renderReturnParameters(returnParameters)};
|
|
18
18
|
`
|
|
19
19
|
)}
|
|
20
20
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { renderList, renderedSolidityHeader } from "./common.js";
|
|
2
|
+
import { TableOptions } from "./tableOptions.js";
|
|
3
|
+
|
|
4
|
+
export function renderTableIndex(options: TableOptions[]) {
|
|
5
|
+
return `${renderedSolidityHeader}
|
|
6
|
+
|
|
7
|
+
${renderList(options, ({ outputPath, tableName, renderOptions: { structName, staticResourceData } }) => {
|
|
8
|
+
const imports = [tableName];
|
|
9
|
+
if (structName) imports.push(structName);
|
|
10
|
+
if (staticResourceData) imports.push(`${tableName}TableId`);
|
|
11
|
+
|
|
12
|
+
return `import { ${imports.join(", ")} } from "./${outputPath}";`;
|
|
13
|
+
})}
|
|
14
|
+
`;
|
|
15
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { SchemaTypeArrayToElement } from "@latticexyz/schema-type";
|
|
3
|
-
import { StoreConfig } from "
|
|
3
|
+
import { StoreConfig } from "@latticexyz/config";
|
|
4
4
|
import {
|
|
5
5
|
ImportDatum,
|
|
6
6
|
RenderTableDynamicField,
|
|
@@ -80,7 +80,7 @@ export function getTableOptions(config: StoreConfig): TableOptions[] {
|
|
|
80
80
|
return {
|
|
81
81
|
tableIdName: tableName + "TableId",
|
|
82
82
|
namespace: config.namespace,
|
|
83
|
-
|
|
83
|
+
name: tableData.name,
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
})();
|
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from "fs";
|
|
2
1
|
import path from "path";
|
|
3
|
-
import { StoreConfig } from "
|
|
4
|
-
import { formatSolidity } from "../utils/format.js";
|
|
2
|
+
import { StoreConfig } from "@latticexyz/config";
|
|
5
3
|
import { getTableOptions } from "./tableOptions.js";
|
|
6
4
|
import { renderTable } from "./renderTable.js";
|
|
7
5
|
import { renderTypesFromConfig } from "./renderTypesFromConfig.js";
|
|
6
|
+
import { formatAndWriteSolidity } from "../utils/formatAndWrite.js";
|
|
7
|
+
import { renderTableIndex } from "./renderTableIndex.js";
|
|
8
|
+
import { rmSync } from "fs";
|
|
8
9
|
|
|
9
10
|
export async function tablegen(config: StoreConfig, outputBaseDirectory: string) {
|
|
10
11
|
const allTableOptions = getTableOptions(config);
|
|
12
|
+
|
|
13
|
+
const uniqueTableDirectories = new Set(allTableOptions.map(({ outputPath }) => path.dirname(outputPath)));
|
|
14
|
+
for (const tableDir of uniqueTableDirectories) {
|
|
15
|
+
rmSync(path.join(outputBaseDirectory, tableDir), { recursive: true, force: true });
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
// write tables to files
|
|
12
19
|
for (const { outputPath, renderOptions } of allTableOptions) {
|
|
13
20
|
const fullOutputPath = path.join(outputBaseDirectory, outputPath);
|
|
14
21
|
const output = renderTable(renderOptions);
|
|
15
|
-
|
|
22
|
+
formatAndWriteSolidity(output, fullOutputPath, "Generated table");
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
// write types to file
|
|
19
26
|
if (Object.keys(config.enums).length > 0) {
|
|
20
27
|
const fullOutputPath = path.join(outputBaseDirectory, `${config.userTypesPath}.sol`);
|
|
21
28
|
const output = renderTypesFromConfig(config);
|
|
22
|
-
|
|
29
|
+
formatAndWriteSolidity(output, fullOutputPath, "Generated types file");
|
|
23
30
|
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function formatAndWrite(output: string, fullOutputPath: string, logPrefix: string) {
|
|
27
|
-
const formattedOutput = await formatSolidity(output);
|
|
28
|
-
|
|
29
|
-
mkdirSync(path.dirname(fullOutputPath), { recursive: true });
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const fullOutputPath = path.join(outputBaseDirectory, `Tables.sol`);
|
|
33
|
+
const output = renderTableIndex(allTableOptions);
|
|
34
|
+
formatAndWriteSolidity(output, fullOutputPath, "Generated table index");
|
|
33
35
|
}
|
|
@@ -29,7 +29,7 @@ export interface StaticResourceData {
|
|
|
29
29
|
/** Name of the table id constant to render. */
|
|
30
30
|
tableIdName: string;
|
|
31
31
|
namespace: string;
|
|
32
|
-
|
|
32
|
+
name: string;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface RenderTableType {
|
|
@@ -95,6 +95,7 @@ export interface RenderSystemInterfaceOptions {
|
|
|
95
95
|
export interface RenderSystemInterfaceFunction {
|
|
96
96
|
name: string;
|
|
97
97
|
parameters: string[];
|
|
98
|
+
stateMutability: string;
|
|
98
99
|
returnParameters: string[];
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AbiTypeToSchemaType, getStaticByteLength, SchemaType, SchemaTypeToAbiType } from "@latticexyz/schema-type";
|
|
2
|
-
import { StoreConfig } from "
|
|
2
|
+
import { StoreConfig, parseStaticArray } from "@latticexyz/config";
|
|
3
3
|
import { ImportDatum, RenderTableType } from "./types.js";
|
|
4
|
-
import { parseStaticArray } from "../config/validation.js";
|
|
5
4
|
|
|
6
5
|
export type UserTypeInfo = ReturnType<typeof getUserTypeInfo>;
|
|
7
6
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { readFileSync } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { MUDConfig } from "
|
|
3
|
+
import { MUDConfig } from "@latticexyz/config";
|
|
4
4
|
import { contractToInterface } from "../utils/contractToInterface.js";
|
|
5
|
-
import {
|
|
5
|
+
import { formatAndWriteSolidity } from "../utils/formatAndWrite.js";
|
|
6
6
|
import { renderSystemInterface } from "./renderSystemInterface.js";
|
|
7
7
|
import { renderWorld } from "./renderWorld.js";
|
|
8
8
|
import { ImportDatum } from "./types.js";
|
|
@@ -27,16 +27,16 @@ export async function worldgen(
|
|
|
27
27
|
}));
|
|
28
28
|
const systemInterfaceName = `I${system.basename}`;
|
|
29
29
|
// create an interface using the external functions and imports
|
|
30
|
-
const {
|
|
30
|
+
const { name } = config.systems[system.basename];
|
|
31
31
|
const output = renderSystemInterface({
|
|
32
32
|
name: systemInterfaceName,
|
|
33
|
-
functionPrefix: config.namespace === "" ? "" : `${config.namespace}_${
|
|
33
|
+
functionPrefix: config.namespace === "" ? "" : `${config.namespace}_${name}_`,
|
|
34
34
|
functions,
|
|
35
35
|
imports,
|
|
36
36
|
});
|
|
37
37
|
// write to file
|
|
38
38
|
const fullOutputPath = path.join(worldgenBaseDirectory, systemInterfaceName + ".sol");
|
|
39
|
-
await
|
|
39
|
+
await formatAndWriteSolidity(output, fullOutputPath, "Generated system interface");
|
|
40
40
|
|
|
41
41
|
// prepare imports for IWorld
|
|
42
42
|
systemInterfaceImports.push({
|
|
@@ -47,14 +47,13 @@ export async function worldgen(
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// render IWorld
|
|
50
|
-
const worldInterfaceName = "IWorld";
|
|
51
50
|
const output = renderWorld({
|
|
52
|
-
interfaceName: worldInterfaceName,
|
|
51
|
+
interfaceName: config.worldInterfaceName,
|
|
53
52
|
imports: systemInterfaceImports,
|
|
54
53
|
storeImportPath: config.storeImportPath,
|
|
55
54
|
worldImportPath: config.worldImportPath,
|
|
56
55
|
});
|
|
57
56
|
// write to file
|
|
58
|
-
const fullOutputPath = path.join(worldgenBaseDirectory, worldInterfaceName + ".sol");
|
|
59
|
-
await
|
|
57
|
+
const fullOutputPath = path.join(worldgenBaseDirectory, config.worldInterfaceName + ".sol");
|
|
58
|
+
await formatAndWriteSolidity(output, fullOutputPath, "Generated system interface");
|
|
60
59
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { StoreConfig } from "@latticexyz/config";
|
|
2
|
+
import { resolveAbiOrUserType } from "../render-solidity/userType.js";
|
|
3
|
+
import { schemaTypesToRecsTypeStrings } from "./schemaTypesToRecsTypeStrings.js";
|
|
4
|
+
import { RecsV1TableOptions } from "./types.js";
|
|
5
|
+
|
|
6
|
+
export function getRecsV1TableOptions(config: StoreConfig): RecsV1TableOptions {
|
|
7
|
+
const tableOptions = [];
|
|
8
|
+
for (const tableName of Object.keys(config.tables)) {
|
|
9
|
+
const tableData = config.tables[tableName];
|
|
10
|
+
|
|
11
|
+
const fields = Object.keys(tableData.schema).map((name) => {
|
|
12
|
+
const abiOrUserType = tableData.schema[name];
|
|
13
|
+
const { schemaType } = resolveAbiOrUserType(abiOrUserType, config);
|
|
14
|
+
|
|
15
|
+
const recsTypeString = schemaTypesToRecsTypeStrings[schemaType];
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
recsTypeString,
|
|
19
|
+
name,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// WARNING: skip tables without a static tableId
|
|
24
|
+
if (tableData.tableIdArgument) continue;
|
|
25
|
+
const staticResourceData = {
|
|
26
|
+
namespace: config.namespace,
|
|
27
|
+
name: tableData.name,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
tableOptions.push({
|
|
31
|
+
tableName,
|
|
32
|
+
fields,
|
|
33
|
+
staticResourceData,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
tables: tableOptions,
|
|
38
|
+
};
|
|
39
|
+
}
|