diff --git a/packages/common/src/codegen/utils/extractUserTypes.ts b/packages/common/src/codegen/utils/extractUserTypes.ts index eab2aa716c..9d738bb79e 100644 --- a/packages/common/src/codegen/utils/extractUserTypes.ts +++ b/packages/common/src/codegen/utils/extractUserTypes.ts @@ -6,6 +6,7 @@ export interface SolidityUserDefinedType { internalTypeId: string; importSymbol: string; fromPath: string; + isRelativePath: boolean; } /** @@ -20,6 +21,7 @@ export function extractUserTypes( ): Record { const ast = parse(data); + const isRelativePath = fromPath.indexOf(".") === 0; const userDefinedTypes: Record = {}; visit(ast, { @@ -36,6 +38,7 @@ export function extractUserTypes( internalTypeId: definition.name, importSymbol: parent.name, fromPath, + isRelativePath, }; } else { userDefinedTypes[name] = { @@ -43,6 +46,7 @@ export function extractUserTypes( internalTypeId: definition.name, importSymbol: name, fromPath, + isRelativePath, }; } } diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index ad0b6d9cab..c76add3a1e 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -3,7 +3,7 @@ import { renderArguments, renderCommonData, renderList, - renderRelativeImports, + renderImports, renderTableId, renderTypeHelpers, renderWithStore, @@ -58,7 +58,7 @@ export function renderTable(options: RenderTableOptions) { imports.length > 0 ? ` // Import user types - ${renderRelativeImports(imports)} + ${renderImports(imports)} ` : "" } diff --git a/packages/store/ts/codegen/tableOptions.ts b/packages/store/ts/codegen/tableOptions.ts index ab26f98a83..2af97d6998 100644 --- a/packages/store/ts/codegen/tableOptions.ts +++ b/packages/store/ts/codegen/tableOptions.ts @@ -1,14 +1,12 @@ -import { readFileSync } from "fs"; import path from "path"; import { SchemaTypeArrayToElement } from "@latticexyz/schema-type/deprecated"; import { - RelativeImportDatum, + ImportDatum, RenderDynamicField, RenderField, RenderKeyTuple, RenderStaticField, SolidityUserDefinedType, - extractUserTypes, } from "@latticexyz/common/codegen"; import { RenderTableOptions } from "./types"; import { StoreConfig } from "../config"; @@ -20,9 +18,11 @@ export interface TableOptions { renderOptions: RenderTableOptions; } -export function getTableOptions(config: StoreConfig): TableOptions[] { +export function getTableOptions( + config: StoreConfig, + solidityUserTypes: Record +): TableOptions[] { const storeImportPath = config.storeImportPath; - const solidityUserTypes = loadAndExtractUserTypes(config.userTypes); const options = []; for (const tableName of Object.keys(config.tables)) { @@ -35,7 +35,7 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { // field methods can include simply get/set if there's only 1 field and no record methods const withSuffixlessFieldMethods = !withRecordMethods && Object.keys(tableData.valueSchema).length === 1; // list of any symbols that need to be imported - const imports: RelativeImportDatum[] = []; + const imports: ImportDatum[] = []; const keyTuple = Object.keys(tableData.keySchema).map((name) => { const abiOrUserType = tableData.keySchema[name]; @@ -110,19 +110,3 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { } return options; } - -function loadAndExtractUserTypes(userTypes: StoreConfig["userTypes"]) { - const userTypesPerFile: Record = {}; - for (const [userTypeName, filePath] of Object.entries(userTypes)) { - if (!(filePath in userTypesPerFile)) { - userTypesPerFile[filePath] = []; - } - userTypesPerFile[filePath].push(userTypeName); - } - let extractedUserTypes: Record = {}; - for (const [filePath, userTypeNames] of Object.entries(userTypesPerFile)) { - const data = readFileSync(filePath, "utf8"); - extractedUserTypes = Object.assign(userTypes, extractUserTypes(data, userTypeNames, filePath)); - } - return extractedUserTypes; -} diff --git a/packages/store/ts/codegen/tablegen.ts b/packages/store/ts/codegen/tablegen.ts index 9852081a41..5fd256b158 100644 --- a/packages/store/ts/codegen/tablegen.ts +++ b/packages/store/ts/codegen/tablegen.ts @@ -1,14 +1,15 @@ import path from "path"; -import { formatAndWriteSolidity } from "@latticexyz/common/codegen"; +import { SolidityUserDefinedType, extractUserTypes, formatAndWriteSolidity } from "@latticexyz/common/codegen"; import { getTableOptions } from "./tableOptions"; import { renderTable } from "./renderTable"; import { renderTypesFromConfig } from "./renderTypesFromConfig"; import { renderTableIndex } from "./renderTableIndex"; -import { rmSync } from "fs"; +import { readFileSync, rmSync } from "fs"; import { StoreConfig } from "../config"; export async function tablegen(config: StoreConfig, outputBaseDirectory: string) { - const allTableOptions = getTableOptions(config); + const solidityUserTypes = loadAndExtractUserTypes(config.userTypes, outputBaseDirectory); + const allTableOptions = getTableOptions(config, solidityUserTypes); const uniqueTableDirectories = new Set(allTableOptions.map(({ outputPath }) => path.dirname(outputPath))); for (const tableDir of uniqueTableDirectories) { @@ -33,3 +34,34 @@ export async function tablegen(config: StoreConfig, outputBaseDirectory: string) const output = renderTableIndex(allTableOptions); await formatAndWriteSolidity(output, fullOutputPath, "Generated table index"); } + +function loadAndExtractUserTypes(userTypes: StoreConfig["userTypes"], outputBaseDirectory: string) { + const userTypesPerFile: Record = {}; + for (const [userTypeName, unresolvedFilePath] of Object.entries(userTypes)) { + if (!(unresolvedFilePath in userTypesPerFile)) { + userTypesPerFile[unresolvedFilePath] = []; + } + userTypesPerFile[unresolvedFilePath].push(userTypeName); + } + let extractedUserTypes: Record = {}; + for (const [unresolvedFilePath, userTypeNames] of Object.entries(userTypesPerFile)) { + const { filePath, data } = loadUserTypesFile(outputBaseDirectory, unresolvedFilePath); + extractedUserTypes = Object.assign(userTypes, extractUserTypes(data, userTypeNames, filePath)); + } + return extractedUserTypes; +} + +function loadUserTypesFile(outputBaseDirectory: string, unresolvedFilePath: string) { + if (unresolvedFilePath.indexOf(".") === 0) { + return { + filePath: path.relative(outputBaseDirectory, unresolvedFilePath), + data: readFileSync(unresolvedFilePath, "utf8"), + }; + } else { + // TODO support remappings + return { + filePath: unresolvedFilePath, + data: readFileSync(path.join("node_modules", unresolvedFilePath), "utf8"), + }; + } +} diff --git a/packages/store/ts/codegen/types.ts b/packages/store/ts/codegen/types.ts index ff01d2e2de..f801c12c24 100644 --- a/packages/store/ts/codegen/types.ts +++ b/packages/store/ts/codegen/types.ts @@ -1,5 +1,5 @@ import { - RelativeImportDatum, + ImportDatum, RenderDynamicField, RenderField, RenderKeyTuple, @@ -9,7 +9,7 @@ import { export interface RenderTableOptions { /** List of symbols to import, and their file paths */ - imports: RelativeImportDatum[]; + imports: ImportDatum[]; /** Name of the library to render. */ libraryName: string; /** Name of the struct to render. If undefined, struct and its methods aren't rendered. */ diff --git a/packages/store/ts/codegen/userType.ts b/packages/store/ts/codegen/userType.ts index db95f3c949..3f6b3c6b13 100644 --- a/packages/store/ts/codegen/userType.ts +++ b/packages/store/ts/codegen/userType.ts @@ -5,7 +5,7 @@ import { SchemaTypeToAbiType, } from "@latticexyz/schema-type/deprecated"; import { parseStaticArray } from "@latticexyz/config"; -import { RelativeImportDatum, RenderType, SolidityUserDefinedType } from "@latticexyz/common/codegen"; +import { ImportDatum, RenderType, SolidityUserDefinedType } from "@latticexyz/common/codegen"; import { StoreConfig } from "../config"; export type UserTypeInfo = ReturnType; @@ -50,7 +50,7 @@ export function importForAbiOrUserType( usedInDirectory: string, config: StoreConfig, solidityUserTypes: Record -): RelativeImportDatum | undefined { +): ImportDatum | undefined { // abi types which directly mirror a SchemaType if (abiOrUserType in AbiTypeToSchemaType) { return undefined; @@ -64,11 +64,19 @@ export function importForAbiOrUserType( if (abiOrUserType in solidityUserTypes) { // these types can have a library name as their import symbol const solidityUserType = solidityUserTypes[abiOrUserType]; - return { - symbol: solidityUserType.importSymbol, - fromPath: solidityUserType.fromPath, - usedInPath: usedInDirectory, - }; + const symbol = solidityUserType.importSymbol; + if (solidityUserType.isRelativePath) { + return { + symbol, + fromPath: solidityUserType.fromPath, + usedInPath: usedInDirectory, + }; + } else { + return { + symbol, + path: solidityUserType.fromPath, + }; + } } // other user types return { @@ -128,7 +136,7 @@ export function getUserTypeInfo( throw new Error(`User type "${userType}" not found in MUD config`); } const solidityUserType = solidityUserTypes[userType]; - const schemaType = AbiTypeToSchemaType[solidityUserType.typeId]; + const schemaType = AbiTypeToSchemaType[solidityUserType.internalTypeId]; return { schemaType, renderType: {