From 69eb63b5939c30515a62da9afbdd71f89a67f8a2 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 26 Jul 2024 12:28:07 +0100 Subject: [PATCH] refactor(store): update tablegen with namespaces output (#2972) --- .changeset/shaggy-weeks-grab.md | 8 + .../src/codegen/world/ICustomErrorsSystem.sol | 2 +- .../src/codegen/world/IStructSystem.sol | 2 +- .../contracts/src/codegen/tables/Statics.sol | 2 +- .../src/codegen/tables/UserTyped.sol | 2 +- packages/cli/scripts/generate-test-tables.ts | 21 ++- packages/cli/src/build.ts | 6 +- packages/cli/src/commands/tablegen.ts | 4 +- .../src/codegen/render-solidity/common.ts | 8 +- .../src/codegen/render-solidity/index.ts | 1 + .../render-solidity/renderImportPath.test.ts | 83 +++++++++++ .../render-solidity/renderImportPath.ts | 24 +++ packages/common/src/foundry/index.ts | 9 -- packages/store/mud.config.ts | 2 +- packages/store/src/codegen/tables/Hooks.sol | 2 +- .../store/src/codegen/tables/ResourceIds.sol | 2 +- .../store/src/codegen/tables/StoreHooks.sol | 2 +- packages/store/src/codegen/tables/Tables.sol | 6 +- .../store/test/codegen/tables/KeyEncoding.sol | 2 +- .../{tableOptions.ts => getTableOptions.ts} | 71 +++++---- .../store/ts/codegen/getUserTypes.test.ts | 14 ++ packages/store/ts/codegen/getUserTypes.ts | 48 ++++++ .../store/ts/codegen/getUserTypesFilename.ts | 9 ++ packages/store/ts/codegen/index.ts | 2 +- packages/store/ts/codegen/renderTable.ts | 23 +-- packages/store/ts/codegen/renderTableIndex.ts | 9 +- packages/store/ts/codegen/tablegen.ts | 86 ++++++----- packages/store/ts/codegen/userType.ts | 138 ++++++------------ packages/store/ts/config/v2/defaults.ts | 2 +- packages/store/ts/config/v2/output.ts | 11 +- packages/store/ts/scripts/build.ts | 4 +- .../store/ts/scripts/generate-test-tables.ts | 11 +- .../interfaces/IAccessManagementSystem.sol | 2 +- .../codegen/interfaces/IBatchCallSystem.sol | 2 +- .../interfaces/IModuleInstallationSystem.sol | 2 +- .../interfaces/IWorldRegistrationSystem.sol | 4 +- .../render-solidity/renderWorldInterface.ts | 2 +- packages/world/ts/scripts/build.ts | 4 +- .../world/ts/scripts/generate-test-tables.ts | 5 +- .../src/codegen/tables/Terrain.sol | 2 +- 40 files changed, 390 insertions(+), 249 deletions(-) create mode 100644 .changeset/shaggy-weeks-grab.md create mode 100644 packages/common/src/codegen/render-solidity/renderImportPath.test.ts create mode 100644 packages/common/src/codegen/render-solidity/renderImportPath.ts rename packages/store/ts/codegen/{tableOptions.ts => getTableOptions.ts} (64%) create mode 100644 packages/store/ts/codegen/getUserTypes.test.ts create mode 100644 packages/store/ts/codegen/getUserTypes.ts create mode 100644 packages/store/ts/codegen/getUserTypesFilename.ts diff --git a/.changeset/shaggy-weeks-grab.md b/.changeset/shaggy-weeks-grab.md new file mode 100644 index 0000000000..c55bc884f2 --- /dev/null +++ b/.changeset/shaggy-weeks-grab.md @@ -0,0 +1,8 @@ +--- +"@latticexyz/store": patch +--- + +Refactored tablegen in preparation for multiple namespaces and addressed a few edge cases: + +- User types configured with a relative `filePath` are now resolved relative to the project root (where the `mud.config.ts` lives) rather than the current working directory. +- User types inside libraries now need to be referenced with their fully-qualified code path (e.g. `LibraryName.UserTypeName`). diff --git a/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol b/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol index ce3085beda..47e672d4d9 100644 --- a/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol +++ b/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ -import { Position } from "./../../CustomTypes.sol"; +import { Position } from "../../CustomTypes.sol"; /** * @title ICustomErrorsSystem diff --git a/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol b/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol index a95d9eb919..e25284fbfe 100644 --- a/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol +++ b/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ -import { BytesStruct, StringStruct } from "./../../systems/structs.sol"; +import { BytesStruct, StringStruct } from "../../systems/structs.sol"; /** * @title IStructSystem diff --git a/packages/cli/contracts/src/codegen/tables/Statics.sol b/packages/cli/contracts/src/codegen/tables/Statics.sol index 83b959c491..ebba037d3f 100644 --- a/packages/cli/contracts/src/codegen/tables/Statics.sol +++ b/packages/cli/contracts/src/codegen/tables/Statics.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/Encoded import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; // Import user types -import { Enum2, Enum1 } from "./../common.sol"; +import { Enum2, Enum1 } from "../common.sol"; struct StaticsData { uint256 v1; diff --git a/packages/cli/contracts/src/codegen/tables/UserTyped.sol b/packages/cli/contracts/src/codegen/tables/UserTyped.sol index 5e05f4d1a9..bf0f26ef18 100644 --- a/packages/cli/contracts/src/codegen/tables/UserTyped.sol +++ b/packages/cli/contracts/src/codegen/tables/UserTyped.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/Encoded import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; // Import user types -import { TestTypeAddress, TestTypeInt64, TestTypeLibrary } from "./../../types.sol"; +import { TestTypeAddress, TestTypeInt64, TestTypeLibrary } from "../../types.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; struct UserTypedData { diff --git a/packages/cli/scripts/generate-test-tables.ts b/packages/cli/scripts/generate-test-tables.ts index a564fdfdf1..15d1df9cfd 100644 --- a/packages/cli/scripts/generate-test-tables.ts +++ b/packages/cli/scripts/generate-test-tables.ts @@ -1,6 +1,5 @@ import { tablegen } from "@latticexyz/store/codegen"; import { defineStore } from "@latticexyz/store"; -import { getRemappings } from "@latticexyz/common/foundry"; import { fileURLToPath } from "node:url"; import path from "node:path"; @@ -16,10 +15,10 @@ const config = defineStore({ Enum2: ["E1"], }, userTypes: { - TestTypeAddress: { filePath: "./contracts/src/types.sol", type: "address" }, - TestTypeInt64: { filePath: "./contracts/src/types.sol", type: "int64" }, - TestTypeBool: { filePath: "./contracts/src/types.sol", type: "bool" }, - TestTypeUint128: { filePath: "./contracts/src/types.sol", type: "uint128" }, + TestTypeAddress: { filePath: "../contracts/src/types.sol", type: "address" }, + TestTypeInt64: { filePath: "../contracts/src/types.sol", type: "int64" }, + "TestTypeLibrary.TestTypeBool": { filePath: "../contracts/src/types.sol", type: "bool" }, + "TestTypeLibrary.TestTypeUint128": { filePath: "../contracts/src/types.sol", type: "uint128" }, ResourceId: { filePath: "@latticexyz/store/src/ResourceId.sol", type: "bytes32" }, }, tables: { @@ -82,13 +81,13 @@ const config = defineStore({ schema: { k1: "TestTypeAddress", k2: "TestTypeInt64", - k3: "TestTypeBool", - k4: "TestTypeUint128", + k3: "TestTypeLibrary.TestTypeBool", + k4: "TestTypeLibrary.TestTypeUint128", k5: "ResourceId", v1: "TestTypeAddress", v2: "TestTypeInt64", - v3: "TestTypeBool", - v4: "TestTypeUint128", + v3: "TestTypeLibrary.TestTypeBool", + v4: "TestTypeLibrary.TestTypeUint128", v5: "ResourceId", }, key: ["k1", "k2", "k3", "k4", "k5"], @@ -96,6 +95,4 @@ const config = defineStore({ }, }); -const remappings = await getRemappings(); - -await tablegen({ rootDir: path.dirname(configPath), config, remappings }); +await tablegen({ rootDir: path.dirname(configPath), config }); diff --git a/packages/cli/src/build.ts b/packages/cli/src/build.ts index 849558b7c1..1413aae58c 100644 --- a/packages/cli/src/build.ts +++ b/packages/cli/src/build.ts @@ -1,7 +1,7 @@ import { tablegen } from "@latticexyz/store/codegen"; import { worldgen } from "@latticexyz/world/node"; import { World as WorldConfig } from "@latticexyz/world"; -import { forge, getRemappings } from "@latticexyz/common/foundry"; +import { forge } from "@latticexyz/common/foundry"; import { execa } from "execa"; type BuildOptions = { @@ -20,9 +20,7 @@ export async function build({ config, foundryProfile = process.env.FOUNDRY_PROFILE, }: BuildOptions): Promise { - const remappings = await getRemappings(foundryProfile); - - await Promise.all([tablegen({ rootDir, config, remappings }), worldgen({ rootDir, config })]); + await Promise.all([tablegen({ rootDir, config }), worldgen({ rootDir, config })]); await forge(["build"], { profile: foundryProfile }); await execa("mud", ["abi-ts"], { stdio: "inherit" }); diff --git a/packages/cli/src/commands/tablegen.ts b/packages/cli/src/commands/tablegen.ts index cc406dc1bd..d0030b6283 100644 --- a/packages/cli/src/commands/tablegen.ts +++ b/packages/cli/src/commands/tablegen.ts @@ -2,7 +2,6 @@ import type { CommandModule } from "yargs"; import { loadConfig, resolveConfigPath } from "@latticexyz/config/node"; import { Store as StoreConfig } from "@latticexyz/store"; import { tablegen } from "@latticexyz/store/codegen"; -import { getRemappings } from "@latticexyz/common/foundry"; import path from "node:path"; type Options = { @@ -23,9 +22,8 @@ const commandModule: CommandModule = { async handler(opts) { const configPath = await resolveConfigPath(opts.configPath); const config = (await loadConfig(configPath)) as StoreConfig; - const remappings = await getRemappings(); - await tablegen({ rootDir: path.dirname(configPath), config, remappings }); + await tablegen({ rootDir: path.dirname(configPath), config }); process.exit(0); }, diff --git a/packages/common/src/codegen/render-solidity/common.ts b/packages/common/src/codegen/render-solidity/common.ts index f0b284d169..f73a5162d7 100644 --- a/packages/common/src/codegen/render-solidity/common.ts +++ b/packages/common/src/codegen/render-solidity/common.ts @@ -10,6 +10,7 @@ import { import { posixPath } from "../utils"; import { resourceToHex } from "../../resourceToHex"; import { hexToResource } from "../../hexToResource"; +import { renderImportPath } from "./renderImportPath"; /** * Common header for all codegenerated solidity files @@ -72,7 +73,10 @@ export function renderCommonData({ }; } -/** For 2 paths which are relative to a common root, create a relative import path from one to another */ +/** + * For 2 paths which are relative to a common root, create a relative import path from one to another + * @deprecated Use `renderImportPath` instead. + */ export function solidityRelativeImportPath(fromPath: string, usedInPath: string): string { // 1st "./" must be added because path strips it, // but solidity expects it unless there's "../" ("./../" is fine). @@ -129,7 +133,7 @@ export function renderAbsoluteImports(imports: AbsoluteImportDatum[]): string { const renderedImports = []; for (const [path, symbols] of aggregatedImports) { const renderedSymbols = [...symbols].join(", "); - renderedImports.push(`import { ${renderedSymbols} } from "${posixPath(path)}";`); + renderedImports.push(`import { ${renderedSymbols} } from "${renderImportPath(path)}";`); } return renderedImports.join("\n"); } diff --git a/packages/common/src/codegen/render-solidity/index.ts b/packages/common/src/codegen/render-solidity/index.ts index 126d991c28..1a9c63f824 100644 --- a/packages/common/src/codegen/render-solidity/index.ts +++ b/packages/common/src/codegen/render-solidity/index.ts @@ -1,4 +1,5 @@ export * from "./common"; export * from "./renderEnums"; +export * from "./renderImportPath"; export * from "./renderTypeHelpers"; export * from "./types"; diff --git a/packages/common/src/codegen/render-solidity/renderImportPath.test.ts b/packages/common/src/codegen/render-solidity/renderImportPath.test.ts new file mode 100644 index 0000000000..1dc0ae4125 --- /dev/null +++ b/packages/common/src/codegen/render-solidity/renderImportPath.test.ts @@ -0,0 +1,83 @@ +import { describe, expect, it } from "vitest"; +import { renderImportPath } from "./renderImportPath"; + +describe("renderImportPath", () => { + it("returns valid path for package imports", () => { + expect(renderImportPath("@latticexyz/store/src")).toMatchInlineSnapshot('"@latticexyz/store/src"'); + expect(renderImportPath("@latticexyz/store/src/")).toMatchInlineSnapshot('"@latticexyz/store/src"'); + expect(renderImportPath("@latticexyz/store/src", "IStore.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/src/IStore.sol"', + ); + expect(renderImportPath("@latticexyz/store/src/", "IStore.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/src/IStore.sol"', + ); + expect(renderImportPath("@latticexyz/store/src", "codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("@latticexyz/store/src/", "codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("@latticexyz/store/src", "./codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("@latticexyz/store/src/", "./codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("@latticexyz/store/src", "../test/codegen/common.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/test/codegen/common.sol"', + ); + expect(renderImportPath("@latticexyz/store/src/", "../test/codegen/common.sol")).toMatchInlineSnapshot( + '"@latticexyz/store/test/codegen/common.sol"', + ); + }); + + it("returns valid path for relative imports", () => { + expect(renderImportPath(".")).toMatchInlineSnapshot('"."'); + expect(renderImportPath("./")).toMatchInlineSnapshot('"."'); + expect(renderImportPath(".", "IStore.sol")).toMatchInlineSnapshot('"./IStore.sol"'); + expect(renderImportPath("./", "IStore.sol")).toMatchInlineSnapshot('"./IStore.sol"'); + expect(renderImportPath("./src")).toMatchInlineSnapshot('"./src"'); + expect(renderImportPath("./src/")).toMatchInlineSnapshot('"./src"'); + expect(renderImportPath("./src", "IStore.sol")).toMatchInlineSnapshot('"./src/IStore.sol"'); + expect(renderImportPath("../test/", "IStore.sol")).toMatchInlineSnapshot('"../test/IStore.sol"'); + expect(renderImportPath("../test")).toMatchInlineSnapshot('"../test"'); + expect(renderImportPath("../test/")).toMatchInlineSnapshot('"../test"'); + expect(renderImportPath("../test", "IStore.sol")).toMatchInlineSnapshot('"../test/IStore.sol"'); + expect(renderImportPath("../test/", "IStore.sol")).toMatchInlineSnapshot('"../test/IStore.sol"'); + expect(renderImportPath(".", "codegen/tables/Tables.sol")).toMatchInlineSnapshot('"./codegen/tables/Tables.sol"'); + expect(renderImportPath("./", "codegen/tables/Tables.sol")).toMatchInlineSnapshot('"./codegen/tables/Tables.sol"'); + expect(renderImportPath(".", "./codegen/tables/Tables.sol")).toMatchInlineSnapshot('"./codegen/tables/Tables.sol"'); + expect(renderImportPath("./", "./codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"./codegen/tables/Tables.sol"', + ); + expect(renderImportPath(".", "../test/codegen/common.sol")).toMatchInlineSnapshot('"../test/codegen/common.sol"'); + expect(renderImportPath("./", "../test/codegen/common.sol")).toMatchInlineSnapshot('"../test/codegen/common.sol"'); + expect(renderImportPath("./src", "codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"./src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("./src/", "codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"./src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("./src", "./codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"./src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("./src/", "./codegen/tables/Tables.sol")).toMatchInlineSnapshot( + '"./src/codegen/tables/Tables.sol"', + ); + expect(renderImportPath("./src", "../test/codegen/common.sol")).toMatchInlineSnapshot( + '"./test/codegen/common.sol"', + ); + expect(renderImportPath("./src/", "../test/codegen/common.sol")).toMatchInlineSnapshot( + '"./test/codegen/common.sol"', + ); + }); + + it("normalizes to POSIX paths", () => { + expect(renderImportPath("C:\\src")).toMatchInlineSnapshot('"C:/src"'); + expect(renderImportPath("C:\\src\\")).toMatchInlineSnapshot('"C:/src"'); + expect(renderImportPath("C:\\src", "./IStore.sol")).toMatchInlineSnapshot('"C:/src/IStore.sol"'); + expect(renderImportPath("C:\\src\\", "./IStore.sol")).toMatchInlineSnapshot('"C:/src/IStore.sol"'); + expect(renderImportPath("./src", ".\\IStore.sol")).toMatchInlineSnapshot('"./src/IStore.sol"'); + expect(renderImportPath("./src", ".\\IStore.sol")).toMatchInlineSnapshot('"./src/IStore.sol"'); + }); +}); diff --git a/packages/common/src/codegen/render-solidity/renderImportPath.ts b/packages/common/src/codegen/render-solidity/renderImportPath.ts new file mode 100644 index 0000000000..39eb138c4b --- /dev/null +++ b/packages/common/src/codegen/render-solidity/renderImportPath.ts @@ -0,0 +1,24 @@ +import path from "node:path"; + +// This will probably break for backslash-escaped POSIX paths, +// but we'll worry about that later. +function winToPosix(segment: string): string { + return segment.replaceAll(path.win32.sep, path.posix.sep); +} + +export function renderImportPath(basePath: string, ...segments: readonly string[]): string { + // Solidity compiler expects POSIX paths + const fullPath = path.posix + .join(winToPosix(basePath), ...segments.map(winToPosix)) + // remove trailing slash + .replace(/\/$/, ""); + + // `path.join` strips the leading `./` + // so if we started with a relative path, make it relative again + if (basePath.startsWith(".")) { + const relativePath = "./" + fullPath; + return relativePath.replace(/^(\.\/)+\./, "."); + } + + return fullPath; +} diff --git a/packages/common/src/foundry/index.ts b/packages/common/src/foundry/index.ts index 628a98deea..b14d4548b2 100644 --- a/packages/common/src/foundry/index.ts +++ b/packages/common/src/foundry/index.ts @@ -71,15 +71,6 @@ export async function getRpcUrl(profile?: string): Promise { return (await getForgeConfig(profile)).eth_rpc_url || "http://127.0.0.1:8545"; } -/** - * Get the value of "remappings" from forge config - * @param profile The foundry profile to use - * @returns The array of remapping tuples `[from, to]` - */ -export async function getRemappings(profile?: string): Promise<[string, string][]> { - return (await getForgeConfig(profile)).remappings.map((line) => line.trim().split("=")) as [string, string][]; -} - /** * Execute a forge command * @param args The arguments to pass to forge diff --git a/packages/store/mud.config.ts b/packages/store/mud.config.ts index 5c779cd700..f9e958c98f 100644 --- a/packages/store/mud.config.ts +++ b/packages/store/mud.config.ts @@ -2,7 +2,7 @@ import { defineStore } from "./ts/config/v2/store"; export default defineStore({ codegen: { - storeImportPath: "../../", + storeImportPath: "./src", }, namespace: "store", userTypes: { diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index e815dd892d..a0bbf36faf 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "../../EncodedLengths.sol"; import { ResourceId } from "../../ResourceId.sol"; // Import user types -import { ResourceId } from "./../../ResourceId.sol"; +import { ResourceId } from "../../ResourceId.sol"; library Hooks { FieldLayout constant _fieldLayout = diff --git a/packages/store/src/codegen/tables/ResourceIds.sol b/packages/store/src/codegen/tables/ResourceIds.sol index 0caf3ecac7..0e04073444 100644 --- a/packages/store/src/codegen/tables/ResourceIds.sol +++ b/packages/store/src/codegen/tables/ResourceIds.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "../../EncodedLengths.sol"; import { ResourceId } from "../../ResourceId.sol"; // Import user types -import { ResourceId } from "./../../ResourceId.sol"; +import { ResourceId } from "../../ResourceId.sol"; library ResourceIds { // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "store", name: "ResourceIds", typeId: RESOURCE_TABLE });` diff --git a/packages/store/src/codegen/tables/StoreHooks.sol b/packages/store/src/codegen/tables/StoreHooks.sol index c5c474768e..4aac606501 100644 --- a/packages/store/src/codegen/tables/StoreHooks.sol +++ b/packages/store/src/codegen/tables/StoreHooks.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "../../EncodedLengths.sol"; import { ResourceId } from "../../ResourceId.sol"; // Import user types -import { ResourceId } from "./../../ResourceId.sol"; +import { ResourceId } from "../../ResourceId.sol"; library StoreHooks { // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "store", name: "StoreHooks", typeId: RESOURCE_TABLE });` diff --git a/packages/store/src/codegen/tables/Tables.sol b/packages/store/src/codegen/tables/Tables.sol index d034310006..9cbe48f824 100644 --- a/packages/store/src/codegen/tables/Tables.sol +++ b/packages/store/src/codegen/tables/Tables.sol @@ -17,9 +17,9 @@ import { EncodedLengths, EncodedLengthsLib } from "../../EncodedLengths.sol"; import { ResourceId } from "../../ResourceId.sol"; // Import user types -import { ResourceId } from "./../../ResourceId.sol"; -import { FieldLayout } from "./../../FieldLayout.sol"; -import { Schema } from "./../../Schema.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { FieldLayout } from "../../FieldLayout.sol"; +import { Schema } from "../../Schema.sol"; struct TablesData { FieldLayout fieldLayout; diff --git a/packages/store/test/codegen/tables/KeyEncoding.sol b/packages/store/test/codegen/tables/KeyEncoding.sol index 6252ff5200..8004179b40 100644 --- a/packages/store/test/codegen/tables/KeyEncoding.sol +++ b/packages/store/test/codegen/tables/KeyEncoding.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "../../../src/EncodedLengths.s import { ResourceId } from "../../../src/ResourceId.sol"; // Import user types -import { ExampleEnum } from "./../common.sol"; +import { ExampleEnum } from "../common.sol"; library KeyEncoding { // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "", name: "KeyEncoding", typeId: RESOURCE_TABLE });` diff --git a/packages/store/ts/codegen/tableOptions.ts b/packages/store/ts/codegen/getTableOptions.ts similarity index 64% rename from packages/store/ts/codegen/tableOptions.ts rename to packages/store/ts/codegen/getTableOptions.ts index d0959361c1..b8c4f66158 100644 --- a/packages/store/ts/codegen/tableOptions.ts +++ b/packages/store/ts/codegen/getTableOptions.ts @@ -6,12 +6,13 @@ import { RenderField, RenderKeyTuple, RenderStaticField, - SolidityUserDefinedType, } from "@latticexyz/common/codegen"; import { RenderTableOptions } from "./types"; -import { getSchemaTypeInfo, importForAbiOrUserType, resolveAbiOrUserType } from "./userType"; -import { Store as StoreConfig } from "../config/v2/output"; +import { getSchemaTypeInfo, resolveAbiOrUserType } from "./userType"; +import { Table } from "../config/v2/output"; import { getKeySchema, getValueSchema } from "@latticexyz/protocol-parser/internal"; +import { UserType } from "./getUserTypes"; +import { isDefined } from "@latticexyz/common/utils"; export interface TableOptions { /** Path where the file is expected to be written (relative to project root) */ @@ -25,12 +26,24 @@ export interface TableOptions { /** * Transforms store config and available solidity user types into useful options for `tablegen` and `renderTable` */ -export function getTableOptions( - config: StoreConfig, - solidityUserTypes: Record, -): TableOptions[] { - const tables = Object.values(config.namespaces).flatMap((namespace) => Object.values(namespace.tables)); +export function getTableOptions({ + tables, + rootDir, + codegenDir, + userTypes, + storeImportPath, +}: { + readonly tables: Table[]; + readonly rootDir: string; + /** namespace codegen output dir, relative to project root dir */ + readonly codegenDir: string; + readonly userTypes: readonly UserType[]; + /** absolute import path or, if starting with `.`, relative to project root dir */ + readonly storeImportPath: string; +}): TableOptions[] { const options = tables.map((table): TableOptions => { + const outputPath = path.join(rootDir, codegenDir, table.codegen.outputDirectory, `${table.label}.sol`); + const keySchema = getKeySchema(table); const valueSchema = getValueSchema(table); @@ -41,19 +54,22 @@ export function getTableOptions( // field methods can include simply get/set if there's only 1 field and no record methods const withSuffixlessFieldMethods = !withRecordMethods && Object.keys(valueSchema).length === 1; // list of any symbols that need to be imported - const imports: ImportDatum[] = []; + const imports = Object.values(table.schema) + .map((field) => userTypes.find((type) => type.name === field.internalType)) + .filter(isDefined) + .map((userType): ImportDatum => { + return { + // If it's a fully qualified name, remove trailing references + // This enables support for user types inside libraries + symbol: userType.name.replace(/\..*$/, ""), + path: userType.importPath.startsWith(".") + ? "./" + path.relative(path.dirname(outputPath), path.join(rootDir, userType.importPath)) + : userType.importPath, + }; + }); const keyTuple = Object.entries(keySchema).map(([name, field]): RenderKeyTuple => { - const abiOrUserType = field.internalType; - const { renderType } = resolveAbiOrUserType(abiOrUserType, config, solidityUserTypes); - - const importDatum = importForAbiOrUserType( - abiOrUserType, - table.codegen.outputDirectory, - config, - solidityUserTypes, - ); - if (importDatum) imports.push(importDatum); + const { renderType } = resolveAbiOrUserType(field.internalType, userTypes); return { ...renderType, @@ -63,16 +79,7 @@ export function getTableOptions( }); const fields = Object.entries(valueSchema).map(([name, field]): RenderField => { - const abiOrUserType = field.internalType; - const { renderType, schemaType } = resolveAbiOrUserType(abiOrUserType, config, solidityUserTypes); - - const importDatum = importForAbiOrUserType( - abiOrUserType, - table.codegen.outputDirectory, - config, - solidityUserTypes, - ); - if (importDatum) imports.push(importDatum); + const { renderType, schemaType } = resolveAbiOrUserType(field.internalType, userTypes); const elementType = SchemaTypeArrayToElement[schemaType]; return { @@ -96,14 +103,16 @@ export function getTableOptions( }; return { - outputPath: path.join(table.codegen.outputDirectory, `${table.label}.sol`), + outputPath, tableName: table.label, renderOptions: { imports, libraryName: table.label, structName: withStruct ? table.label + "Data" : undefined, staticResourceData, - storeImportPath: config.codegen.storeImportPath, + storeImportPath: storeImportPath.startsWith(".") + ? "./" + path.relative(path.dirname(outputPath), path.join(rootDir, storeImportPath)) + : storeImportPath, keyTuple, fields, staticFields, diff --git a/packages/store/ts/codegen/getUserTypes.test.ts b/packages/store/ts/codegen/getUserTypes.test.ts new file mode 100644 index 0000000000..10ffd9ea7f --- /dev/null +++ b/packages/store/ts/codegen/getUserTypes.test.ts @@ -0,0 +1,14 @@ +import path from "node:path"; +import { describe, expect, it } from "vitest"; + +describe("getUserTypes", () => { + it("should resolve relative import path", () => { + const rootDir = process.cwd(); + const filePath = "./src/MyUserType.sol"; + const tableFilename = "src/codegen/tables/Table.sol"; + + const importPath = path.relative(path.dirname(path.join(rootDir, tableFilename)), path.join(rootDir, filePath)); + + expect(importPath).toMatchInlineSnapshot('"../../MyUserType.sol"'); + }); +}); diff --git a/packages/store/ts/codegen/getUserTypes.ts b/packages/store/ts/codegen/getUserTypes.ts new file mode 100644 index 0000000000..46e1f1b77e --- /dev/null +++ b/packages/store/ts/codegen/getUserTypes.ts @@ -0,0 +1,48 @@ +import { Store } from "../config/v2"; +import { AbiType } from "@latticexyz/config"; +import { getUserTypesFilename } from "./getUserTypesFilename"; +import { groupBy } from "@latticexyz/common/utils"; + +export type UserType = { + readonly type: "enum" | "userType"; + readonly name: string; + readonly abiType: AbiType; + /** + * Import path relative to the root dir or absolute path if importing from a package. + * Relative paths must start with a `.` to be treated as a relative path. + */ + readonly importPath: string; +}; + +export function getUserTypes({ config }: { readonly config: Store }): readonly UserType[] { + const enums = Object.keys(config.enums).map( + (name): UserType => ({ + type: "enum", + name, + abiType: "uint8", + importPath: "./" + getUserTypesFilename({ config }), + }), + ); + + const userTypes = Object.entries(config.userTypes).map( + ([name, userType]): UserType => ({ + type: "userType", + name, + abiType: userType.type, + // If `userType.filePath` starts with a `.`, it's relative to the root dir + importPath: userType.filePath, + }), + ); + + const result = [...enums, ...userTypes]; + + // TODO: move this to config validation step? + const duplicates = Array.from(groupBy(result, (userType) => userType.name).entries()) + .filter(([, entries]) => entries.length > 1) + .map(([name]) => name); + if (duplicates.length > 0) { + throw new Error(`Found enums and user types sharing the same name: ${duplicates.join(", ")}`); + } + + return result; +} diff --git a/packages/store/ts/codegen/getUserTypesFilename.ts b/packages/store/ts/codegen/getUserTypesFilename.ts new file mode 100644 index 0000000000..70a4ecf3ec --- /dev/null +++ b/packages/store/ts/codegen/getUserTypesFilename.ts @@ -0,0 +1,9 @@ +import path from "node:path"; +import { Store } from "../config/v2"; + +/** + * @returns File path for codegen'ed user types, relative to source dir + */ +export function getUserTypesFilename({ config }: { config: Store }): string { + return path.join(config.sourceDirectory, config.codegen.outputDirectory, config.codegen.userTypesFilename); +} diff --git a/packages/store/ts/codegen/index.ts b/packages/store/ts/codegen/index.ts index d5dfbf0f96..112468cd58 100644 --- a/packages/store/ts/codegen/index.ts +++ b/packages/store/ts/codegen/index.ts @@ -3,7 +3,7 @@ export * from "./record"; export * from "./renderTable"; export * from "./renderTypesFromConfig"; export * from "./tablegen"; -export * from "./tableOptions"; +export * from "./getTableOptions"; export * from "./tightcoder"; export * from "./types"; export * from "./userType"; diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index 91b7036dd3..9d65b34052 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -9,6 +9,7 @@ import { renderWithStore, renderedSolidityHeader, RenderStaticField, + renderImportPath, } from "@latticexyz/common/codegen"; import { renderEncodeFieldSingle, renderFieldMethods } from "./field"; import { renderDeleteRecordMethods, renderRecordData, renderRecordMethods } from "./record"; @@ -42,17 +43,17 @@ export function renderTable(options: RenderTableOptions) { ${renderedSolidityHeader} // Import store internals - import { IStore } from "${storeImportPath}IStore.sol"; - import { StoreSwitch } from "${storeImportPath}StoreSwitch.sol"; - import { StoreCore } from "${storeImportPath}StoreCore.sol"; - import { Bytes } from "${storeImportPath}Bytes.sol"; - import { Memory } from "${storeImportPath}Memory.sol"; - import { SliceLib } from "${storeImportPath}Slice.sol"; - import { EncodeArray } from "${storeImportPath}tightcoder/EncodeArray.sol"; - import { FieldLayout } from "${storeImportPath}FieldLayout.sol"; - import { Schema } from "${storeImportPath}Schema.sol"; - import { EncodedLengths, EncodedLengthsLib } from "${storeImportPath}EncodedLengths.sol"; - import { ResourceId } from "${storeImportPath}ResourceId.sol"; + import { IStore } from "${renderImportPath(storeImportPath, "IStore.sol")}"; + import { StoreSwitch } from "${renderImportPath(storeImportPath, "StoreSwitch.sol")}"; + import { StoreCore } from "${renderImportPath(storeImportPath, "StoreCore.sol")}"; + import { Bytes } from "${renderImportPath(storeImportPath, "Bytes.sol")}"; + import { Memory } from "${renderImportPath(storeImportPath, "Memory.sol")}"; + import { SliceLib } from "${renderImportPath(storeImportPath, "Slice.sol")}"; + import { EncodeArray } from "${renderImportPath(storeImportPath, "tightcoder/EncodeArray.sol")}"; + import { FieldLayout } from "${renderImportPath(storeImportPath, "FieldLayout.sol")}"; + import { Schema } from "${renderImportPath(storeImportPath, "Schema.sol")}"; + import { EncodedLengths, EncodedLengthsLib } from "${renderImportPath(storeImportPath, "EncodedLengths.sol")}"; + import { ResourceId } from "${renderImportPath(storeImportPath, "ResourceId.sol")}"; ${ imports.length > 0 diff --git a/packages/store/ts/codegen/renderTableIndex.ts b/packages/store/ts/codegen/renderTableIndex.ts index 1bb5a990f5..69f14f5432 100644 --- a/packages/store/ts/codegen/renderTableIndex.ts +++ b/packages/store/ts/codegen/renderTableIndex.ts @@ -1,12 +1,13 @@ -import { posixPath, renderList, renderedSolidityHeader } from "@latticexyz/common/codegen"; -import { TableOptions } from "./tableOptions"; +import { renderList, renderedSolidityHeader } from "@latticexyz/common/codegen"; +import { TableOptions } from "./getTableOptions"; +import path from "node:path/posix"; /** * Returns Solidity code for table index file that imports all codegen tables * @param options table definitions * @returns string of Solidity code */ -export function renderTableIndex(options: TableOptions[]) { +export function renderTableIndex(codegenIndexPath: string, options: TableOptions[]) { return ` ${renderedSolidityHeader} @@ -14,7 +15,7 @@ export function renderTableIndex(options: TableOptions[]) { const imports = [tableName]; if (structName) imports.push(structName); - return `import { ${imports.join(", ")} } from "./${posixPath(outputPath)}";`; + return `import { ${imports.join(", ")} } from "./${path.relative(path.dirname(codegenIndexPath), outputPath)}";`; })} `; } diff --git a/packages/store/ts/codegen/tablegen.ts b/packages/store/ts/codegen/tablegen.ts index af9c7aa1a7..a31cb3e899 100644 --- a/packages/store/ts/codegen/tablegen.ts +++ b/packages/store/ts/codegen/tablegen.ts @@ -1,12 +1,13 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { formatAndWriteSolidity, loadAndExtractUserTypes } from "@latticexyz/common/codegen"; -import { getTableOptions } from "./tableOptions"; +import { formatAndWriteSolidity, renderEnums } from "@latticexyz/common/codegen"; import { renderTable } from "./renderTable"; -import { renderTypesFromConfig } from "./renderTypesFromConfig"; import { renderTableIndex } from "./renderTableIndex"; import { Store as StoreConfig } from "../config/v2/output"; -import { mapObject } from "@latticexyz/common/utils"; +import { uniqueBy } from "@latticexyz/common/utils"; +import { getUserTypes } from "./getUserTypes"; +import { getUserTypesFilename } from "./getUserTypesFilename"; +import { getTableOptions } from "./getTableOptions"; export type TablegenOptions = { /** @@ -14,45 +15,54 @@ export type TablegenOptions = { */ rootDir: string; config: StoreConfig; - remappings: [string, string][]; }; -export async function tablegen({ rootDir, config, remappings }: TablegenOptions) { - const outputDirectory = path.join(rootDir, config.sourceDirectory, config.codegen.outputDirectory); - const solidityUserTypes = loadAndExtractUserTypes( - mapObject(config.userTypes, (type) => ({ ...type, internalType: type.type })), - outputDirectory, - remappings, - ); - const allTableOptions = getTableOptions(config, solidityUserTypes); +export async function tablegen({ rootDir, config }: TablegenOptions) { + const userTypes = getUserTypes({ config }); - const uniqueTableDirectories = Array.from(new Set(allTableOptions.map(({ outputPath }) => path.dirname(outputPath)))); - await Promise.all( - uniqueTableDirectories.map(async (tableDir) => { - await fs.rm(path.join(outputDirectory, tableDir), { recursive: true, force: true }); - }), - ); + // Write enums to user types file + if (Object.keys(config.enums).length > 0) { + const userTypesFilename = path.join(rootDir, getUserTypesFilename({ config })); + const source = renderEnums(config.enums); + await formatAndWriteSolidity(source, userTypesFilename, "Generated types file with enums"); + } - // write tables to files await Promise.all( - allTableOptions.map(async ({ outputPath, renderOptions }) => { - const fullOutputPath = path.join(outputDirectory, outputPath); - const output = renderTable(renderOptions); - await formatAndWriteSolidity(output, fullOutputPath, "Generated table"); - }), - ); + Object.values(config.namespaces).map(async (namespace) => { + // TODO: get this value from config once multiple namespaces are supported + const multipleNamespaces = false; + const sourceDir = multipleNamespaces + ? path.join(config.sourceDirectory, "namespaces", namespace.label) + : config.sourceDirectory; + const codegenDir = path.join(sourceDir, config.codegen.outputDirectory); - // write table index - if (allTableOptions.length > 0) { - const fullOutputPath = path.join(outputDirectory, config.codegen.indexFilename); - const output = renderTableIndex(allTableOptions); - await formatAndWriteSolidity(output, fullOutputPath, "Generated table index"); - } + const tables = Object.values(namespace.tables); + if (tables.length === 0) return; - // write types to file - if (Object.keys(config.enums).length > 0) { - const fullOutputPath = path.join(outputDirectory, config.codegen.userTypesFilename); - const output = renderTypesFromConfig(config); - await formatAndWriteSolidity(output, fullOutputPath, "Generated types file"); - } + const tableOptions = getTableOptions({ + tables, + rootDir, + codegenDir, + userTypes, + storeImportPath: config.codegen.storeImportPath, + }); + + const tableDirs = uniqueBy( + tableOptions.map(({ outputPath }) => path.dirname(outputPath)), + (dir) => dir, + ); + await Promise.all(tableDirs.map((dir) => fs.rm(dir, { recursive: true, force: true }))); + + await Promise.all( + tableOptions.map(async ({ outputPath, renderOptions }) => { + const source = renderTable(renderOptions); + return await formatAndWriteSolidity(source, outputPath, "Generated table"); + }), + ); + + const codegenIndexPath = path.join(rootDir, codegenDir, config.codegen.indexFilename); + const source = renderTableIndex(codegenIndexPath, tableOptions); + await formatAndWriteSolidity(source, codegenIndexPath, "Generated table index"); + }), + ); } diff --git a/packages/store/ts/codegen/userType.ts b/packages/store/ts/codegen/userType.ts index 395b542cfa..3748d8b387 100644 --- a/packages/store/ts/codegen/userType.ts +++ b/packages/store/ts/codegen/userType.ts @@ -4,8 +4,8 @@ import { SchemaType, SchemaTypeToAbiType, } from "@latticexyz/schema-type/deprecated"; -import { ImportDatum, RenderType, SolidityUserDefinedType } from "@latticexyz/common/codegen"; -import { Store as StoreConfig } from "../config/v2/output"; +import { RenderType } from "@latticexyz/common/codegen"; +import { UserType } from "./getUserTypes"; function parseStaticArray(abiType: string) { const matches = abiType.match(/^(\w+)\[(\d+)\]$/); @@ -21,8 +21,7 @@ function parseStaticArray(abiType: string) { */ export function resolveAbiOrUserType( abiOrUserType: string, - config: StoreConfig, - solidityUserTypes: Record, + userTypes: readonly UserType[], ): { schemaType: SchemaType; renderType: RenderType; @@ -44,52 +43,13 @@ export function resolveAbiOrUserType( throw new Error("Static arrays of user types are not supported"); } } - // user types - return getUserTypeInfo(abiOrUserType, config, solidityUserTypes); -} -/** - * Get the required import for SchemaType|userType (`undefined` means that no import is required) - */ -export function importForAbiOrUserType( - abiOrUserType: string, - usedInDirectory: string, - config: StoreConfig, - solidityUserTypes: Record, -): ImportDatum | undefined { - // abi types which directly mirror a SchemaType - if (abiOrUserType in AbiTypeToSchemaType) { - return undefined; - } - // static arrays - const staticArray = parseStaticArray(abiOrUserType); - if (staticArray) { - return undefined; - } - // user-defined types in a user-provided file - if (abiOrUserType in solidityUserTypes) { - // these types can have a library name as their import symbol - const solidityUserType = solidityUserTypes[abiOrUserType]; - const symbol = solidityUserType.importSymbol; - if (solidityUserType.isRelativePath) { - return { - symbol, - fromPath: solidityUserType.fromPath, - usedInPath: usedInDirectory, - }; - } else { - return { - symbol, - path: solidityUserType.fromPath, - }; - } + // user types + const userType = userTypes.find((type) => type.name === abiOrUserType); + if (!userType) { + throw new Error(`User type "${abiOrUserType}" not found`); } - // other user types - return { - symbol: abiOrUserType, - fromPath: config.codegen.userTypesFilename, - usedInPath: usedInDirectory, - }; + return getUserTypeInfo(userType); } export function getSchemaTypeInfo(schemaType: SchemaType): RenderType { @@ -108,58 +68,46 @@ export function getSchemaTypeInfo(schemaType: SchemaType): RenderType { }; } -export function getUserTypeInfo( - userType: string, - config: StoreConfig, - solidityUserTypes: Record, -): { +export function getUserTypeInfo(userType: UserType): { schemaType: SchemaType; renderType: RenderType; } { - // enums - if (userType in config.enums) { - const schemaType = SchemaType.UINT8; - const staticByteLength = getStaticByteLength(schemaType); - const isDynamic = staticByteLength === 0; - const typeId = userType; - return { - schemaType, - renderType: { - typeId, - typeWithLocation: typeId, - enumName: SchemaType[schemaType], - staticByteLength, - isDynamic, - typeWrap: `${userType}`, - typeUnwrap: `uint8`, - internalTypeId: `${SchemaTypeToAbiType[schemaType]}`, - }, - }; - } - // user-defined types - if (userType in solidityUserTypes) { - if (!(userType in solidityUserTypes)) { - throw new Error(`User type "${userType}" not found in MUD config`); + switch (userType.type) { + case "enum": { + const schemaType = SchemaType.UINT8; + const staticByteLength = getStaticByteLength(schemaType); + const isDynamic = staticByteLength === 0; + return { + schemaType, + renderType: { + typeId: userType.name, + typeWithLocation: userType.name, + enumName: SchemaType[schemaType], + staticByteLength, + isDynamic, + typeWrap: userType.name, + typeUnwrap: userType.abiType, + internalTypeId: userType.abiType, + }, + }; + } + case "userType": { + const schemaType = AbiTypeToSchemaType[userType.abiType]; + return { + schemaType, + renderType: { + typeId: userType.name, + typeWithLocation: userType.name, + enumName: SchemaType[schemaType], + staticByteLength: getStaticByteLength(schemaType), + isDynamic: false, + typeWrap: `${userType.name}.wrap`, + typeUnwrap: `${userType.name}.unwrap`, + internalTypeId: userType.abiType, + }, + }; } - const solidityUserType = solidityUserTypes[userType]; - const typeId = solidityUserType.typeId; - const schemaType = AbiTypeToSchemaType[solidityUserType.internalTypeId]; - return { - schemaType, - renderType: { - typeId, - typeWithLocation: typeId, - enumName: SchemaType[schemaType], - staticByteLength: getStaticByteLength(schemaType), - isDynamic: false, - typeWrap: `${typeId}.wrap`, - typeUnwrap: `${typeId}.unwrap`, - internalTypeId: solidityUserType.internalTypeId, - }, - }; } - // invalid - throw new Error(`User type "${userType}" does not exist`); } function getStaticArrayTypeInfo(abiType: string, elementType: string, staticLength: number) { diff --git a/packages/store/ts/config/v2/defaults.ts b/packages/store/ts/config/v2/defaults.ts index 9c1899f343..eb5e0cb957 100644 --- a/packages/store/ts/config/v2/defaults.ts +++ b/packages/store/ts/config/v2/defaults.ts @@ -1,7 +1,7 @@ import { CodegenInput, StoreInput, TableCodegenInput, TableDeployInput, TableInput } from "./input"; export const CODEGEN_DEFAULTS = { - storeImportPath: "@latticexyz/store/src/", + storeImportPath: "@latticexyz/store/src", userTypesFilename: "common.sol", outputDirectory: "codegen", // TODO: default to true if using top-level `namespaces` key (once its migrated to store) diff --git a/packages/store/ts/config/v2/output.ts b/packages/store/ts/config/v2/output.ts index 4d10e71a71..f882e7a470 100644 --- a/packages/store/ts/config/v2/output.ts +++ b/packages/store/ts/config/v2/output.ts @@ -11,6 +11,8 @@ export type UserTypes = { }; }; +export type Enums = EnumsInput; + export type EnumValues = { readonly [enumName: string]: { readonly [enumElement: string]: number; @@ -45,7 +47,12 @@ export type Tables = { }; export type Codegen = { - /** @internal */ + /** + * @internal + * Absolute import path for a package import or starting with `.` for an import relative to project root dir. + * + * Defaults to `@latticexyz/store/src` if not set. + */ readonly storeImportPath: string; readonly userTypesFilename: string; /** @@ -92,7 +99,7 @@ export type Store = Omit & { */ readonly sourceDirectory: string; readonly userTypes: UserTypes; - readonly enums: EnumsInput; + readonly enums: Enums; readonly enumValues: EnumValues; readonly codegen: Codegen; readonly namespaces: Namespaces; diff --git a/packages/store/ts/scripts/build.ts b/packages/store/ts/scripts/build.ts index b207284106..ad74d9828e 100644 --- a/packages/store/ts/scripts/build.ts +++ b/packages/store/ts/scripts/build.ts @@ -1,11 +1,9 @@ import { loadConfig, resolveConfigPath } from "@latticexyz/config/node"; -import { getRemappings } from "@latticexyz/common/foundry"; import { tablegen } from "../codegen"; import { Store as StoreConfig } from "../config/v2/output"; import path from "node:path"; const configPath = await resolveConfigPath(undefined); const config = (await loadConfig(configPath)) as StoreConfig; -const remappings = await getRemappings(); -await tablegen({ rootDir: path.dirname(configPath), config, remappings }); +await tablegen({ rootDir: path.dirname(configPath), config }); diff --git a/packages/store/ts/scripts/generate-test-tables.ts b/packages/store/ts/scripts/generate-test-tables.ts index 0a61b15d24..8d659a03e0 100644 --- a/packages/store/ts/scripts/generate-test-tables.ts +++ b/packages/store/ts/scripts/generate-test-tables.ts @@ -1,15 +1,14 @@ -import { getRemappings } from "@latticexyz/common/foundry"; import { tablegen } from "../codegen"; import { defineStore } from "../config/v2/store"; import { fileURLToPath } from "node:url"; import path from "node:path"; -const configPath = fileURLToPath(import.meta.url); +const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const config = defineStore({ - sourceDirectory: "../../test", + sourceDirectory: "test", codegen: { - storeImportPath: "../../../src/", + storeImportPath: "./src", }, enums: { ExampleEnum: ["None", "First", "Second", "Third"], @@ -52,6 +51,4 @@ const config = defineStore({ }, }); -const remappings = await getRemappings(); - -await tablegen({ rootDir: path.dirname(configPath), config, remappings }); +await tablegen({ rootDir, config }); diff --git a/packages/world/src/codegen/interfaces/IAccessManagementSystem.sol b/packages/world/src/codegen/interfaces/IAccessManagementSystem.sol index fac3eb1116..cc7284c71d 100644 --- a/packages/world/src/codegen/interfaces/IAccessManagementSystem.sol +++ b/packages/world/src/codegen/interfaces/IAccessManagementSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ -import { ResourceId } from "./../../WorldResourceId.sol"; +import { ResourceId } from "../../WorldResourceId.sol"; /** * @title IAccessManagementSystem diff --git a/packages/world/src/codegen/interfaces/IBatchCallSystem.sol b/packages/world/src/codegen/interfaces/IBatchCallSystem.sol index c6f95b5489..6555140871 100644 --- a/packages/world/src/codegen/interfaces/IBatchCallSystem.sol +++ b/packages/world/src/codegen/interfaces/IBatchCallSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ -import { SystemCallData, SystemCallFromData } from "./../../modules/init/types.sol"; +import { SystemCallData, SystemCallFromData } from "../../modules/init/types.sol"; /** * @title IBatchCallSystem diff --git a/packages/world/src/codegen/interfaces/IModuleInstallationSystem.sol b/packages/world/src/codegen/interfaces/IModuleInstallationSystem.sol index 80fb477ecf..cb4504bd49 100644 --- a/packages/world/src/codegen/interfaces/IModuleInstallationSystem.sol +++ b/packages/world/src/codegen/interfaces/IModuleInstallationSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ -import { IModule } from "./../../IModule.sol"; +import { IModule } from "../../IModule.sol"; /** * @title IModuleInstallationSystem diff --git a/packages/world/src/codegen/interfaces/IWorldRegistrationSystem.sol b/packages/world/src/codegen/interfaces/IWorldRegistrationSystem.sol index 7db5058421..276f3ea674 100644 --- a/packages/world/src/codegen/interfaces/IWorldRegistrationSystem.sol +++ b/packages/world/src/codegen/interfaces/IWorldRegistrationSystem.sol @@ -4,8 +4,8 @@ pragma solidity >=0.8.24; /* Autogenerated file. Do not edit manually. */ import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { ISystemHook } from "./../../ISystemHook.sol"; -import { System } from "./../../System.sol"; +import { ISystemHook } from "../../ISystemHook.sol"; +import { System } from "../../System.sol"; /** * @title IWorldRegistrationSystem diff --git a/packages/world/ts/node/render-solidity/renderWorldInterface.ts b/packages/world/ts/node/render-solidity/renderWorldInterface.ts index 3391bec587..92b3980325 100644 --- a/packages/world/ts/node/render-solidity/renderWorldInterface.ts +++ b/packages/world/ts/node/render-solidity/renderWorldInterface.ts @@ -12,7 +12,7 @@ export function renderWorldInterface(options: RenderWorldOptions) { const baseImports: AbsoluteImportDatum[] = interfaceName === "IBaseWorld" ? [ - { symbol: "IStore", path: `${storeImportPath}IStore.sol` }, + { symbol: "IStore", path: `${storeImportPath}/IStore.sol` }, { symbol: "IWorldKernel", path: `${worldImportPath}IWorldKernel.sol` }, ] : [ diff --git a/packages/world/ts/scripts/build.ts b/packages/world/ts/scripts/build.ts index 8a44243225..75e5630967 100644 --- a/packages/world/ts/scripts/build.ts +++ b/packages/world/ts/scripts/build.ts @@ -1,6 +1,5 @@ import path from "node:path"; import { loadConfig, resolveConfigPath } from "@latticexyz/config/node"; -import { getRemappings } from "@latticexyz/common/foundry"; import { tablegen } from "@latticexyz/store/codegen"; import { World } from "../config/v2"; import { worldgen } from "../node"; @@ -15,10 +14,9 @@ import { worldgen } from "../node"; const configPath = await resolveConfigPath(); const rootDir = path.dirname(configPath); const config = (await loadConfig(configPath)) as World; -const remappings = await getRemappings(); await Promise.all([ - tablegen({ rootDir, config, remappings }), + tablegen({ rootDir, config }), worldgen({ rootDir, config: { diff --git a/packages/world/ts/scripts/generate-test-tables.ts b/packages/world/ts/scripts/generate-test-tables.ts index 392596fd96..eb382c1c82 100644 --- a/packages/world/ts/scripts/generate-test-tables.ts +++ b/packages/world/ts/scripts/generate-test-tables.ts @@ -1,4 +1,3 @@ -import { getRemappings } from "@latticexyz/common/foundry"; import { tablegen } from "@latticexyz/store/codegen"; import { defineWorld } from "../config/v2/world"; import { fileURLToPath } from "node:url"; @@ -41,6 +40,4 @@ const config = defineWorld({ }, }); -const remappings = await getRemappings(); - -await tablegen({ rootDir: path.dirname(configPath), config, remappings }); +await tablegen({ rootDir: path.dirname(configPath), config }); diff --git a/test/mock-game-contracts/src/codegen/tables/Terrain.sol b/test/mock-game-contracts/src/codegen/tables/Terrain.sol index 3476bc100a..bc4bb03c23 100644 --- a/test/mock-game-contracts/src/codegen/tables/Terrain.sol +++ b/test/mock-game-contracts/src/codegen/tables/Terrain.sol @@ -17,7 +17,7 @@ import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/Encoded import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; // Import user types -import { TerrainType } from "./../common.sol"; +import { TerrainType } from "../common.sol"; library Terrain { // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "", name: "Terrain", typeId: RESOURCE_TABLE });`