From 4412aab42b8707084e57609fcea52808e22bb357 Mon Sep 17 00:00:00 2001 From: dk1a Date: Fri, 17 Mar 2023 23:39:16 +0300 Subject: [PATCH 1/7] feat(cli): use abi types in store config --- packages/cli/package.json | 4 +- packages/cli/scripts/codegen.ts | 27 +++-- packages/cli/src/config/commonSchemas.ts | 12 +- packages/cli/src/config/index.ts | 11 +- .../cli/src/config/parseStoreConfig.test-d.ts | 4 +- packages/cli/src/config/parseStoreConfig.ts | 103 ++++++++++-------- packages/cli/src/index.ts | 1 + .../cli/src/render-solidity/tableOptions.ts | 14 +-- packages/cli/src/render-solidity/userType.ts | 34 +++--- packages/cli/src/utils/deploy-v2.ts | 10 +- packages/cli/src/utils/typeUtils.ts | 5 + .../schema-type/src/typescript/AbiTypes.ts | 5 + .../src/typescript/SchemaTypeToAbiType.ts | 2 +- .../src/typescript/StaticAbiTypes.ts | 10 ++ packages/schema-type/src/typescript/index.ts | 4 + packages/store/mud.config.mts | 31 +++--- packages/world/mud.config.mts | 53 +++++---- yarn.lock | 16 +-- 18 files changed, 191 insertions(+), 155 deletions(-) create mode 100644 packages/cli/src/utils/typeUtils.ts create mode 100644 packages/schema-type/src/typescript/AbiTypes.ts create mode 100644 packages/schema-type/src/typescript/StaticAbiTypes.ts diff --git a/packages/cli/package.json b/packages/cli/package.json index ef9308ce8c..d6c07742ef 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -67,8 +67,8 @@ "typechain": "^8.1.1", "typescript": "^4.9.5", "yargs": "^17.7.1", - "zod": "^3.20.6", - "zod-validation-error": "^0.3.2" + "zod": "^3.21.4", + "zod-validation-error": "^1.0.1" }, "gitHead": "914a1e0ae4a573d685841ca2ea921435057deb8f" } diff --git a/packages/cli/scripts/codegen.ts b/packages/cli/scripts/codegen.ts index f5163f8412..3b138c1580 100644 --- a/packages/cli/scripts/codegen.ts +++ b/packages/cli/scripts/codegen.ts @@ -1,28 +1,27 @@ -import { SchemaType } from "@latticexyz/schema-type"; -import { parseStoreConfig, StoreUserConfig } from "../src/config/index.js"; +import { defineStoreUserConfig, parseStoreConfig } from "../src/config/index.js"; import { tablegen } from "../src/render-solidity/tablegen.js"; import { logError } from "../src/utils/errors.js"; import { getSrcDirectory } from "../src/utils/foundry.js"; // This config is used only for tests -const config: StoreUserConfig = { +const config = defineStoreUserConfig({ tables: { Table1: { primaryKeys: { - k1: SchemaType.UINT256, - k2: SchemaType.INT32, - k3: SchemaType.BYTES16, - k4: SchemaType.ADDRESS, - k5: SchemaType.BOOL, + k1: "uint256", + k2: "int32", + k3: "bytes16", + k4: "address", + k5: "bool", k6: "Enum1", k7: "Enum2", }, schema: { - v1: SchemaType.UINT256, - v2: SchemaType.INT32, - v3: SchemaType.BYTES16, - v4: SchemaType.ADDRESS, - v5: SchemaType.BOOL, + v1: "uint256", + v2: "int32", + v3: "bytes16", + v4: "address", + v5: "bool", v6: "Enum1", v7: "Enum2", }, @@ -35,7 +34,7 @@ const config: StoreUserConfig = { Enum2: ["E1"], }, }, -}; +}); // Aside from avoiding `mud.config.mts` in cli package (could cause issues), // this also tests that tablegen can work as a standalone function diff --git a/packages/cli/src/config/commonSchemas.ts b/packages/cli/src/config/commonSchemas.ts index fb4044007d..099e4648ac 100644 --- a/packages/cli/src/config/commonSchemas.ts +++ b/packages/cli/src/config/commonSchemas.ts @@ -1,4 +1,4 @@ -import { getStaticByteLength, SchemaType } from "@latticexyz/schema-type"; +import { AbiType, AbiTypes, StaticAbiType, StaticAbiTypes } from "@latticexyz/schema-type"; import { z } from "zod"; import { validateBaseRoute, @@ -31,10 +31,14 @@ export const BaseRoute = z.string().superRefine(validateBaseRoute); /** A valid Ethereum address */ export const EthereumAddress = z.string().superRefine(validateEthereumAddress); +export const zAbiType = z + .string() + .refine((val): val is AbiType => (AbiTypes as string[]).includes(val), "Invalid abi type"); + /** Static subset of SchemaType enum */ -export const StaticSchemaType = z - .nativeEnum(SchemaType) - .refine((arg) => getStaticByteLength(arg) > 0, "SchemaType must be static"); +export const zStaticAbiType = z + .string() + .refine((val): val is AbiType => (StaticAbiTypes as string[]).includes(val), "Abi type must be static"); /** A selector for namespace/file/resource */ export const Selector = z.string().superRefine(validateSelector); diff --git a/packages/cli/src/config/index.ts b/packages/cli/src/config/index.ts index d6b8996170..5b92ed8112 100644 --- a/packages/cli/src/config/index.ts +++ b/packages/cli/src/config/index.ts @@ -1,9 +1,18 @@ +import { StringForUnion } from "../utils/typeUtils.js"; import { StoreUserConfig, StoreConfig } from "./parseStoreConfig.js"; import { WorldUserConfig, ResolvedWorldConfig } from "./world/index.js"; -export type MUDUserConfig = StoreUserConfig & WorldUserConfig; +export type MUDUserConfig = StoreUserConfig & + WorldUserConfig; export type MUDConfig = StoreConfig & ResolvedWorldConfig; +/** Type helper for defining MUDUserConfig */ +export function defineMUDUserConfig( + config: MUDUserConfig +) { + return config; +} + export * from "./commonSchemas.js"; export * from "./loadConfig.js"; export * from "./loadStoreConfig.js"; diff --git a/packages/cli/src/config/parseStoreConfig.test-d.ts b/packages/cli/src/config/parseStoreConfig.test-d.ts index 2eea3ef79a..14072ccb4b 100644 --- a/packages/cli/src/config/parseStoreConfig.test-d.ts +++ b/packages/cli/src/config/parseStoreConfig.test-d.ts @@ -7,8 +7,8 @@ describe("StoreUserConfig", () => { expectTypeOf().toEqualTypeOf>(); // type equality isn't deep for optionals expectTypeOf().toEqualTypeOf["tables"][string]>(); - expectTypeOf[string]>().toEqualTypeOf< - NonNullable["enums"]>[string] + expectTypeOf["enums"]>[string]>().toEqualTypeOf< + NonNullable>["enums"]>[string] >(); // TODO If more nested schemas are added, provide separate tests for them }); diff --git a/packages/cli/src/config/parseStoreConfig.ts b/packages/cli/src/config/parseStoreConfig.ts index ad92670906..f979b99b79 100644 --- a/packages/cli/src/config/parseStoreConfig.ts +++ b/packages/cli/src/config/parseStoreConfig.ts @@ -1,6 +1,7 @@ -import { SchemaType } from "@latticexyz/schema-type"; +import { AbiType, AbiTypes, StaticAbiType } from "@latticexyz/schema-type"; import { RefinementCtx, z, ZodIssueCode } from "zod"; -import { ObjectName, Selector, StaticSchemaType, UserEnum, ValueName } from "./commonSchemas.js"; +import { RequireKeys, StringForUnion } from "../utils/typeUtils.js"; +import { ObjectName, Selector, zAbiType, zStaticAbiType, UserEnum, ValueName } from "./commonSchemas.js"; import { getDuplicates } from "./validation.js"; const TableName = ObjectName; @@ -8,12 +9,17 @@ const KeyName = ValueName; const ColumnName = ValueName; const UserEnumName = ObjectName; -// Fields can use SchemaType or one of user defined wrapper types -const FieldData = z.union([z.nativeEnum(SchemaType), UserEnumName]); +// Fields can use AbiType or one of user-defined wrapper types +// (user types are refined later, based on the appropriate config options) +const zFieldData = z.union([zAbiType, z.string()]); -// Primary keys allow only static types, but allow static user defined types -const PrimaryKey = z.union([StaticSchemaType, UserEnumName]); -const PrimaryKeys = z.record(KeyName, PrimaryKey).default({ key: SchemaType.BYTES32 }); +type FieldData = AbiType | UserTypes; + +// Primary keys allow only static types +const zPrimaryKey = z.union([zStaticAbiType, z.string()]); +const zPrimaryKeys = z.record(KeyName, zPrimaryKey).default({ key: "bytes32" }); + +type PrimaryKey = StaticAbiType | StaticUserTypes; /************************************************************************ * @@ -21,21 +27,21 @@ const PrimaryKeys = z.record(KeyName, PrimaryKey).default({ key: SchemaType.BYTE * ************************************************************************/ -export type FullSchemaConfig = Record>; -export type ShorthandSchemaConfig = z.input; -export type SchemaConfig = FullSchemaConfig | ShorthandSchemaConfig; +export type FullSchemaConfig = Record>; +export type ShorthandSchemaConfig = FieldData; +export type SchemaConfig = FullSchemaConfig | ShorthandSchemaConfig; -const FullSchemaConfig = z - .record(ColumnName, FieldData) +const zFullSchemaConfig = z + .record(ColumnName, zFieldData) .refine((arg) => Object.keys(arg).length > 0, "Table schema may not be empty"); -const ShorthandSchemaConfig = FieldData.transform((fieldData) => { - return FullSchemaConfig.parse({ +const zShorthandSchemaConfig = zFieldData.transform((fieldData) => { + return zFullSchemaConfig.parse({ value: fieldData, }); }); -export const SchemaConfig = FullSchemaConfig.or(ShorthandSchemaConfig); +export const zSchemaConfig = zFullSchemaConfig.or(zShorthandSchemaConfig); /************************************************************************ * @@ -43,7 +49,7 @@ export const SchemaConfig = FullSchemaConfig.or(ShorthandSchemaConfig); * ************************************************************************/ -export interface TableConfig { +export interface TableConfig { /** Output directory path for the file. Default is "tables" */ directory?: string; /** @@ -58,20 +64,20 @@ export interface TableConfig { storeArgument?: boolean; /** Include a data struct and methods for it. Default is false for 1-column tables; true for multi-column tables. */ dataStruct?: boolean; - /** Table's primary key names mapped to their types. Default is `{ key: SchemaType.BYTES32 }` */ - primaryKeys?: Record>; + /** Table's primary key names mapped to their types. Default is `{ key: "bytes32" }` */ + primaryKeys?: Record>; /** Table's column names mapped to their types. Table name's 1st letter should be lowercase. */ - schema: SchemaConfig; + schema: SchemaConfig; } -const FullTableConfig = z +const zFullTableConfig = z .object({ directory: z.string().default("tables"), fileSelector: Selector.optional(), tableIdArgument: z.boolean().default(false), storeArgument: z.boolean().default(false), - primaryKeys: PrimaryKeys, - schema: SchemaConfig, + primaryKeys: zPrimaryKeys, + schema: zSchemaConfig, dataStruct: z.boolean().optional(), }) .transform((arg) => { @@ -84,15 +90,15 @@ const FullTableConfig = z return arg as RequireKeys; }); -const ShorthandTableConfig = FieldData.transform((fieldData) => { - return FullTableConfig.parse({ +const zShorthandTableConfig = zFieldData.transform((fieldData) => { + return zFullTableConfig.parse({ schema: { value: fieldData, }, }); }); -export const TableConfig = FullTableConfig.or(ShorthandTableConfig); +export const zTableConfig = zFullTableConfig.or(zShorthandTableConfig); /************************************************************************ * @@ -100,9 +106,9 @@ export const TableConfig = FullTableConfig.or(ShorthandTableConfig); * ************************************************************************/ -export type TablesConfig = Record>; +export type TablesConfig = Record | FieldData>; -export const TablesConfig = z.record(TableName, TableConfig).transform((tables) => { +export const zTablesConfig = z.record(TableName, zTableConfig).transform((tables) => { // default fileSelector depends on tableName for (const tableName of Object.keys(tables)) { const table = tables[tableName]; @@ -119,14 +125,14 @@ export const TablesConfig = z.record(TableName, TableConfig).transform((tables) * ************************************************************************/ -export interface UserTypesConfig = Record> { +export interface UserTypesConfig { /** Path to the file where common types will be generated and imported from. Default is "Types" */ path?: string; /** Enum names mapped to lists of their member names */ - enums?: Enums; + enums?: Record; } -export const UserTypesConfig = z +export const zUserTypesConfig = z .object({ path: z.string().default("Types"), enums: z.record(UserEnumName, UserEnum).default({}), @@ -140,7 +146,7 @@ export const UserTypesConfig = z ************************************************************************/ // zod doesn't preserve doc comments -export interface StoreUserConfig { +export interface StoreUserConfig { /** The namespace for table ids. Default is "" (empty string) */ namespace?: string; /** Path for store package imports. Default is "@latticexyz/store/src/" */ @@ -151,12 +157,19 @@ export interface StoreUserConfig { * The key is the table name (capitalized). * * The value: - * - `SchemaType | userType` for a single-value table (aka ECS component). + * - abi or user type for a single-value table (aka ECS component). * - FullTableConfig object for multi-value tables (or for customizable options). */ - tables: TablesConfig; - /** User-defined types that will be generated and may be used in table schemas instead of `SchemaType` */ - userTypes?: UserTypesConfig; + tables: TablesConfig; + /** User-defined types that will be generated and may be used in table schemas instead of abi types */ + userTypes?: UserTypesConfig; +} + +/** Type helper for defining StoreUserConfig */ +export function defineStoreUserConfig( + config: StoreUserConfig +) { + return config; } export type StoreConfig = z.output; @@ -164,8 +177,8 @@ export type StoreConfig = z.output; const StoreConfigUnrefined = z.object({ namespace: Selector.default(""), storeImportPath: z.string().default("@latticexyz/store/src/"), - tables: TablesConfig, - userTypes: UserTypesConfig, + tables: zTablesConfig, + userTypes: zUserTypesConfig, }); // finally validate global conditions @@ -209,25 +222,19 @@ function validateStoreConfig(config: z.output, ctx: // User types must exist for (const table of Object.values(config.tables)) { for (const primaryKeyType of Object.values(table.primaryKeys)) { - validateIfUserType(userTypeNames, primaryKeyType, ctx); + validateAbiOrUserType(userTypeNames, primaryKeyType, ctx); } for (const fieldType of Object.values(table.schema)) { - validateIfUserType(userTypeNames, fieldType, ctx); + validateAbiOrUserType(userTypeNames, fieldType, ctx); } } } -function validateIfUserType( - userTypeNames: string[], - type: z.output | z.output, - ctx: RefinementCtx -) { - if (typeof type === "string" && !userTypeNames.includes(type)) { +function validateAbiOrUserType(userTypeNames: string[], type: string, ctx: RefinementCtx) { + if (!(AbiTypes as string[]).includes(type) && !userTypeNames.includes(type)) { ctx.addIssue({ code: ZodIssueCode.custom, - message: `User type ${type} is not defined in userTypes`, + message: `${type} is not a valid abi type, and is not defined in userTypes`, }); } } - -type RequireKeys, P extends string> = T & Required>; diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 0472559b92..714cb4fb6e 100755 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -13,6 +13,7 @@ export type { MUDUserConfig, MUDConfig, } from "./config/index.js"; +export { defineStoreUserConfig, defineMUDUserConfig } from "./config/index.js"; export * from "./constants.js"; export * from "./utils/index.js"; diff --git a/packages/cli/src/render-solidity/tableOptions.ts b/packages/cli/src/render-solidity/tableOptions.ts index 709b170826..1ff4fd7e05 100644 --- a/packages/cli/src/render-solidity/tableOptions.ts +++ b/packages/cli/src/render-solidity/tableOptions.ts @@ -9,7 +9,7 @@ import { RenderTablePrimaryKey, RenderTableStaticField, } from "./types.js"; -import { getSchemaTypeInfo, importForSchemaOrUserType, resolveSchemaOrUserType } from "./userType.js"; +import { getSchemaTypeInfo, importForAbiOrUserType, resolveAbiOrUserType } from "./userType.js"; export interface TableOptions { outputPath: string; @@ -34,10 +34,10 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { const imports: ImportDatum[] = []; const primaryKeys = Object.keys(tableData.primaryKeys).map((name) => { - const schemaOrUserType = tableData.primaryKeys[name]; - const { renderTableType } = resolveSchemaOrUserType(schemaOrUserType, config.userTypes); + const abiOrUserType = tableData.primaryKeys[name]; + const { renderTableType } = resolveAbiOrUserType(abiOrUserType, config.userTypes); - const importDatum = importForSchemaOrUserType(schemaOrUserType, tableData.directory, config.userTypes); + const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config.userTypes); if (importDatum) imports.push(importDatum); if (renderTableType.isDynamic) @@ -52,10 +52,10 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { }); const fields = Object.keys(tableData.schema).map((name) => { - const schemaOrUserType = tableData.schema[name]; - const { renderTableType, schemaType } = resolveSchemaOrUserType(schemaOrUserType, config.userTypes); + const abiOrUserType = tableData.schema[name]; + const { renderTableType, schemaType } = resolveAbiOrUserType(abiOrUserType, config.userTypes); - const importDatum = importForSchemaOrUserType(schemaOrUserType, tableData.directory, config.userTypes); + const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config.userTypes); if (importDatum) imports.push(importDatum); const elementType = SchemaTypeArrayToElement[schemaType]; diff --git a/packages/cli/src/render-solidity/userType.ts b/packages/cli/src/render-solidity/userType.ts index fa19e383a4..977ba2ff16 100644 --- a/packages/cli/src/render-solidity/userType.ts +++ b/packages/cli/src/render-solidity/userType.ts @@ -1,43 +1,41 @@ -import { getStaticByteLength, SchemaType, SchemaTypeToAbiType } from "@latticexyz/schema-type"; +import { AbiTypeToSchemaType, getStaticByteLength, SchemaType, SchemaTypeToAbiType } from "@latticexyz/schema-type"; import { StoreConfig } from "../index.js"; import { ImportDatum, RenderTableType } from "./types.js"; export type UserTypeInfo = ReturnType; /** - * Resolve a SchemaType|userType into a SchemaType + * Resolve an abi or user type into a SchemaType */ -export function resolveSchemaOrUserType( - schemaOrUserType: SchemaType | string, - userTypesConfig: StoreConfig["userTypes"] -) { - if (typeof schemaOrUserType === "string") { - const { schemaType, renderTableType } = getUserTypeInfo(schemaOrUserType, userTypesConfig); - return { schemaType, renderTableType }; - } else { +export function resolveAbiOrUserType(abiOrUserType: string, userTypesConfig: StoreConfig["userTypes"]) { + if (abiOrUserType in AbiTypeToSchemaType) { + const schemaType = AbiTypeToSchemaType[abiOrUserType]; return { - schemaType: schemaOrUserType, - renderTableType: getSchemaTypeInfo(schemaOrUserType), + schemaType, + renderTableType: getSchemaTypeInfo(schemaType), }; + } else { + const { schemaType, renderTableType } = getUserTypeInfo(abiOrUserType, userTypesConfig); + return { schemaType, renderTableType }; } } /** * Get the required import for SchemaType|userType (`undefined` means that no import is required) */ -export function importForSchemaOrUserType( - schemaOrUserType: SchemaType | string, +export function importForAbiOrUserType( + abiOrUserType: string, usedInDirectory: string, userTypesConfig: StoreConfig["userTypes"] ): ImportDatum | undefined { - if (typeof schemaOrUserType === "string") { + if (abiOrUserType in AbiTypeToSchemaType) { + return undefined; + } else { return { - symbol: schemaOrUserType, + symbol: abiOrUserType, fromPath: userTypesConfig.path + ".sol", usedInPath: usedInDirectory, }; - } else { - return undefined; } } diff --git a/packages/cli/src/utils/deploy-v2.ts b/packages/cli/src/utils/deploy-v2.ts index 9ddd4640a3..497bb99120 100644 --- a/packages/cli/src/utils/deploy-v2.ts +++ b/packages/cli/src/utils/deploy-v2.ts @@ -8,7 +8,7 @@ import { IWorld } from "@latticexyz/world/types/ethers-contracts/IWorld.js"; import { ArgumentsType } from "vitest"; import chalk from "chalk"; import { encodeSchema } from "@latticexyz/schema-type"; -import { resolveSchemaOrUserType } from "../render-solidity/userType.js"; +import { resolveAbiOrUserType } from "../render-solidity/userType.js"; import { defaultAbiCoder as abi } from "ethers/lib/utils.js"; import WorldData from "@latticexyz/world/abi/World.json" assert { type: "json" }; @@ -120,13 +120,13 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): tableIds[tableName] = toResourceSelector(namespace, fileSelector); // Register table - const schemaTypes = Object.values(schema).map((schemaOrUserType) => { - const { schemaType } = resolveSchemaOrUserType(schemaOrUserType, mudConfig.userTypes); + const schemaTypes = Object.values(schema).map((abiOrUserType) => { + const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig.userTypes); return schemaType; }); - const keyTypes = Object.values(primaryKeys).map((schemaOrUserType) => { - const { schemaType } = resolveSchemaOrUserType(schemaOrUserType, mudConfig.userTypes); + const keyTypes = Object.values(primaryKeys).map((abiOrUserType) => { + const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig.userTypes); return schemaType; }); diff --git a/packages/cli/src/utils/typeUtils.ts b/packages/cli/src/utils/typeUtils.ts new file mode 100644 index 0000000000..c4ef83043b --- /dev/null +++ b/packages/cli/src/utils/typeUtils.ts @@ -0,0 +1,5 @@ +export type RequireKeys, P extends string> = T & Required>; + +// This allows unions between string literals and `string` without sacrificing autocompletion. +// Workaround for https://github.com/Microsoft/TypeScript/issues/29729 +export type StringForUnion = string & Record; diff --git a/packages/schema-type/src/typescript/AbiTypes.ts b/packages/schema-type/src/typescript/AbiTypes.ts new file mode 100644 index 0000000000..7cc5622531 --- /dev/null +++ b/packages/schema-type/src/typescript/AbiTypes.ts @@ -0,0 +1,5 @@ +import { SchemaType } from "./SchemaType.js"; +import { SchemaTypeToAbiType } from "./SchemaTypeToAbiType.js"; + +export type AbiType = (typeof SchemaTypeToAbiType)[SchemaType]; +export const AbiTypes = Object.values(SchemaTypeToAbiType); diff --git a/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts b/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts index 2260c39118..ebf82e6e4e 100644 --- a/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts +++ b/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts @@ -207,4 +207,4 @@ export const SchemaTypeToAbiType = { [SchemaType.BYTES]: "bytes", [SchemaType.STRING]: "string", -} satisfies Record; +} as const; diff --git a/packages/schema-type/src/typescript/StaticAbiTypes.ts b/packages/schema-type/src/typescript/StaticAbiTypes.ts new file mode 100644 index 0000000000..b092831c10 --- /dev/null +++ b/packages/schema-type/src/typescript/StaticAbiTypes.ts @@ -0,0 +1,10 @@ +import { AbiTypes } from "./AbiTypes.js"; +import { AbiTypeToSchemaType } from "./AbiTypeToSchemaType.js"; +import { getStaticByteLength } from "./getStaticByteLength.js"; +import { SchemaTypeToAbiType } from "./SchemaTypeToAbiType.js"; +import { StaticSchemaType } from "./StaticSchemaType.js"; + +export type StaticAbiType = (typeof SchemaTypeToAbiType)[StaticSchemaType]; +export const StaticAbiTypes = AbiTypes.filter( + (abiType) => getStaticByteLength(AbiTypeToSchemaType[abiType]) > 0 +) as StaticAbiType[]; diff --git a/packages/schema-type/src/typescript/index.ts b/packages/schema-type/src/typescript/index.ts index 7005e14afc..d9869e4098 100644 --- a/packages/schema-type/src/typescript/index.ts +++ b/packages/schema-type/src/typescript/index.ts @@ -2,6 +2,8 @@ export type { StaticSchemaType } from "./StaticSchemaType.js"; export type { DynamicSchemaType } from "./DynamicSchemaType.js"; export type { ArraySchemaType } from "./ArraySchemaType.js"; export type { SchemaTypeToPrimitive } from "./SchemaTypeToPrimitive.js"; +export type { AbiType } from "./AbiTypes.js"; +export type { StaticAbiType } from "./StaticAbiTypes.js"; export { SchemaType } from "./SchemaType.js"; export { encodeSchema } from "./encodeSchema.js"; @@ -9,3 +11,5 @@ export { getStaticByteLength } from "./getStaticByteLength.js"; export { SchemaTypeArrayToElement } from "./SchemaTypeArrayToElement.js"; export { SchemaTypeToAbiType } from "./SchemaTypeToAbiType.js"; export { AbiTypeToSchemaType } from "./AbiTypeToSchemaType.js"; +export { AbiTypes } from "./AbiTypes.js"; +export { StaticAbiTypes } from "./StaticAbiTypes.js"; diff --git a/packages/store/mud.config.mts b/packages/store/mud.config.mts index eb68b08ee6..4e73eff471 100644 --- a/packages/store/mud.config.mts +++ b/packages/store/mud.config.mts @@ -1,37 +1,34 @@ -import { MUDUserConfig } from "@latticexyz/cli"; -import { SchemaType } from "@latticexyz/schema-type"; +import { defineStoreUserConfig } from "@latticexyz/cli"; -const config = { +export default defineStoreUserConfig({ storeImportPath: "../", namespace: "mudstore", tables: { - Hooks: SchemaType.ADDRESS_ARRAY, - Callbacks: SchemaType.BYTES24_ARRAY, + Hooks: "address[]", + Callbacks: "bytes24[]", StoreMetadata: { primaryKeys: { - tableId: SchemaType.UINT256, + tableId: "uint256", }, schema: { - tableName: SchemaType.STRING, - abiEncodedFieldNames: SchemaType.BYTES, + tableName: "string", + abiEncodedFieldNames: "bytes", }, storeArgument: true, }, Mixed: { schema: { - u32: SchemaType.UINT32, - u128: SchemaType.UINT128, - a32: SchemaType.UINT32_ARRAY, - s: SchemaType.STRING, + u32: "uint32", + u128: "uint128", + a32: "uint32[]", + s: "string", }, }, Vector2: { schema: { - x: SchemaType.UINT32, - y: SchemaType.UINT32, + x: "uint32", + y: "uint32", }, }, }, -} satisfies MUDUserConfig; - -export default config; +}); diff --git a/packages/world/mud.config.mts b/packages/world/mud.config.mts index ebbee46d57..f9c1287743 100644 --- a/packages/world/mud.config.mts +++ b/packages/world/mud.config.mts @@ -1,36 +1,35 @@ -import { MUDUserConfig } from "@latticexyz/cli"; -import { SchemaType } from "@latticexyz/schema-type"; +import { defineMUDUserConfig } from "@latticexyz/cli"; -const config = { +export default defineMUDUserConfig({ worldImportPath: "../", worldgenDirectory: "interfaces", tables: { NamespaceOwner: { primaryKeys: { - namespace: SchemaType.BYTES16, + namespace: "bytes16", }, schema: { - owner: SchemaType.ADDRESS, + owner: "address", }, storeArgument: true, }, ResourceAccess: { primaryKeys: { - resourceSelector: SchemaType.BYTES32, - caller: SchemaType.ADDRESS, + resourceSelector: "bytes32", + caller: "address", }, schema: { - access: SchemaType.BOOL, + access: "bool", }, storeArgument: true, }, Systems: { primaryKeys: { - resourceSelector: SchemaType.BYTES32, + resourceSelector: "bytes32", }, schema: { - system: SchemaType.ADDRESS, - publicAccess: SchemaType.BOOL, + system: "address", + publicAccess: "bool", }, storeArgument: true, dataStruct: false, @@ -38,16 +37,16 @@ const config = { SystemRegistry: { directory: "/modules/registration/tables", primaryKeys: { - system: SchemaType.ADDRESS, + system: "address", }, schema: { - resourceSelector: SchemaType.BYTES32, + resourceSelector: "bytes32", }, }, ResourceType: { directory: "/modules/registration/tables", primaryKeys: { - resourceSelector: SchemaType.BYTES32, + resourceSelector: "bytes32", }, schema: { resourceType: "Resource", @@ -56,12 +55,12 @@ const config = { FunctionSelectors: { fileSelector: "funcSelectors", primaryKeys: { - functionSelector: SchemaType.BYTES4, + functionSelector: "bytes4", }, schema: { - namespace: SchemaType.BYTES16, - file: SchemaType.BYTES16, - systemFunctionSelector: SchemaType.BYTES4, + namespace: "bytes16", + file: "bytes16", + systemFunctionSelector: "bytes4", }, dataStruct: false, }, @@ -69,24 +68,24 @@ const config = { // TODO: This table is only used for testing, move it to `test/tables` via the directory config once supported primaryKeys: {}, schema: { - value: SchemaType.BOOL, + value: "bool", }, storeArgument: true, tableIdArgument: true, }, AddressArray: { // TODO: This table is only used for testing, move it to `test/tables` via the directory config once supported - schema: { value: SchemaType.ADDRESS_ARRAY }, + schema: "address[]", storeArgument: true, tableIdArgument: true, }, InstalledModules: { primaryKeys: { - moduleName: SchemaType.BYTES16, - argumentsHash: SchemaType.BYTES32, // Hash of the params passed to the `install` function + moduleName: "bytes16", + argumentsHash: "bytes32", // Hash of the params passed to the `install` function }, schema: { - moduleAddress: SchemaType.ADDRESS, + moduleAddress: "address", }, // TODO: this is a workaround to use `getRecord` instead of `getField` in the autogen library, // to allow using the table before it is registered. This is because `getRecord` passes the schema @@ -97,10 +96,10 @@ const config = { KeysWithValue: { directory: "/modules/keyswithvalue/tables", primaryKeys: { - valueHash: SchemaType.BYTES32, + valueHash: "bytes32", }, schema: { - keysWithValue: SchemaType.BYTES32_ARRAY, // For now only supports 1 key per value + keysWithValue: "bytes32[]", // For now only supports 1 key per value }, tableIdArgument: true, storeArgument: true, @@ -111,6 +110,4 @@ const config = { Resource: ["NONE", "NAMESPACE", "TABLE", "SYSTEM"], }, }, -} satisfies MUDUserConfig; - -export default config; +}); diff --git a/yarn.lock b/yarn.lock index 13e3307956..72ca549c1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16673,12 +16673,12 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== -zod-validation-error@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-0.3.2.tgz#1f09877cd3d671a37d6c0e4e0b7ad42c24d5d8c2" - integrity sha512-pBXItXNDup6KF54fdnA+cmB/eEt65HlN5pmahfBTUhufWEnXs4ouU8lLXh01GoAksIR9K7iF7BxXxkKvct+r+A== +zod-validation-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-1.0.1.tgz#fc8758b667ecdb8121439458c7ab05d0be469b19" + integrity sha512-QRk2AtHLJg8sCZAbEjXSs7E0n4/mSdX5caoh6eOUvDSdcIQz03i0xoNN1Qx6UZT+ADVHRK6+ZXRtldzW6nnltA== -zod@^3.20.6: - version "3.20.6" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.6.tgz#2f2f08ff81291d47d99e86140fedb4e0db08361a" - integrity sha512-oyu0m54SGCtzh6EClBVqDDlAYRz4jrVtKwQ7ZnsEmMI9HnzuZFj8QFwAY1M5uniIYACdGvv0PBWPF2kO0aNofA== +zod@^3.21.4: + version "3.21.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" + integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== From d0f2c71c2e080c971e9dad285ccc0b7ae560150c Mon Sep 17 00:00:00 2001 From: dk1a Date: Fri, 17 Mar 2023 23:43:20 +0300 Subject: [PATCH 2/7] refactor(cli): standardize generic in store config --- packages/cli/src/config/parseStoreConfig.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/config/parseStoreConfig.ts b/packages/cli/src/config/parseStoreConfig.ts index f979b99b79..767d42ac78 100644 --- a/packages/cli/src/config/parseStoreConfig.ts +++ b/packages/cli/src/config/parseStoreConfig.ts @@ -13,13 +13,13 @@ const UserEnumName = ObjectName; // (user types are refined later, based on the appropriate config options) const zFieldData = z.union([zAbiType, z.string()]); -type FieldData = AbiType | UserTypes; +type FieldData = AbiType | UserTypes; // Primary keys allow only static types const zPrimaryKey = z.union([zStaticAbiType, z.string()]); const zPrimaryKeys = z.record(KeyName, zPrimaryKey).default({ key: "bytes32" }); -type PrimaryKey = StaticAbiType | StaticUserTypes; +type PrimaryKey = StaticAbiType | StaticUserTypes; /************************************************************************ * @@ -27,9 +27,11 @@ type PrimaryKey = StaticAbiType | StaticUserType * ************************************************************************/ -export type FullSchemaConfig = Record>; -export type ShorthandSchemaConfig = FieldData; -export type SchemaConfig = FullSchemaConfig | ShorthandSchemaConfig; +export type FullSchemaConfig = Record>; +export type ShorthandSchemaConfig = FieldData; +export type SchemaConfig = + | FullSchemaConfig + | ShorthandSchemaConfig; const zFullSchemaConfig = z .record(ColumnName, zFieldData) @@ -49,7 +51,7 @@ export const zSchemaConfig = zFullSchemaConfig.or(zShorthandSchemaConfig); * ************************************************************************/ -export interface TableConfig { +export interface TableConfig { /** Output directory path for the file. Default is "tables" */ directory?: string; /** @@ -106,7 +108,10 @@ export const zTableConfig = zFullTableConfig.or(zShorthandTableConfig); * ************************************************************************/ -export type TablesConfig = Record | FieldData>; +export type TablesConfig = Record< + string, + TableConfig | FieldData +>; export const zTablesConfig = z.record(TableName, zTableConfig).transform((tables) => { // default fileSelector depends on tableName @@ -125,7 +130,7 @@ export const zTablesConfig = z.record(TableName, zTableConfig).transform((tables * ************************************************************************/ -export interface UserTypesConfig { +export interface UserTypesConfig { /** Path to the file where common types will be generated and imported from. Default is "Types" */ path?: string; /** Enum names mapped to lists of their member names */ From f319d00c82a5111e4ddeba5cf49463b88ce3c3b2 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 18 Mar 2023 00:06:20 +0300 Subject: [PATCH 3/7] chore: cleanup --- packages/cli/src/config/commonSchemas.ts | 2 +- packages/schema-type/src/typescript/SchemaTypeToAbiType.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/config/commonSchemas.ts b/packages/cli/src/config/commonSchemas.ts index 099e4648ac..0ee5806c26 100644 --- a/packages/cli/src/config/commonSchemas.ts +++ b/packages/cli/src/config/commonSchemas.ts @@ -1,4 +1,4 @@ -import { AbiType, AbiTypes, StaticAbiType, StaticAbiTypes } from "@latticexyz/schema-type"; +import { AbiType, AbiTypes, StaticAbiTypes } from "@latticexyz/schema-type"; import { z } from "zod"; import { validateBaseRoute, diff --git a/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts b/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts index ebf82e6e4e..4c0e5d40c2 100644 --- a/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts +++ b/packages/schema-type/src/typescript/SchemaTypeToAbiType.ts @@ -207,4 +207,4 @@ export const SchemaTypeToAbiType = { [SchemaType.BYTES]: "bytes", [SchemaType.STRING]: "string", -} as const; +} as const satisfies Record; From 4c5f70dee242042245ef7211c50895a8f407e6d2 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 18 Mar 2023 00:12:16 +0300 Subject: [PATCH 4/7] refactor(recs): use new config format in defineStoreComponents --- packages/recs/src/v2/abiTypesToRecsTypes.ts | 203 ++++++++++++++++++ packages/recs/src/v2/defineStoreComponents.ts | 26 +-- .../recs/src/v2/schemaTypesToRecsTypes.ts | 203 ------------------ 3 files changed, 216 insertions(+), 216 deletions(-) create mode 100644 packages/recs/src/v2/abiTypesToRecsTypes.ts delete mode 100644 packages/recs/src/v2/schemaTypesToRecsTypes.ts diff --git a/packages/recs/src/v2/abiTypesToRecsTypes.ts b/packages/recs/src/v2/abiTypesToRecsTypes.ts new file mode 100644 index 0000000000..883ac0b108 --- /dev/null +++ b/packages/recs/src/v2/abiTypesToRecsTypes.ts @@ -0,0 +1,203 @@ +import { Type as RecsType } from "../constants"; +import { AbiType } from "@latticexyz/schema-type"; + +export const abiTypesToRecsTypes = { + uint8: RecsType.Number, + uint16: RecsType.Number, + uint24: RecsType.Number, + uint32: RecsType.Number, + uint40: RecsType.Number, + uint48: RecsType.Number, + uint56: RecsType.Number, + uint64: RecsType.Number, + uint72: RecsType.Number, + uint80: RecsType.Number, + uint88: RecsType.Number, + uint96: RecsType.Number, + uint104: RecsType.Number, + uint112: RecsType.Number, + uint120: RecsType.Number, + uint128: RecsType.Number, + uint136: RecsType.Number, + uint144: RecsType.Number, + uint152: RecsType.Number, + uint160: RecsType.Number, + uint168: RecsType.Number, + uint176: RecsType.Number, + uint184: RecsType.Number, + uint192: RecsType.Number, + uint200: RecsType.Number, + uint208: RecsType.Number, + uint216: RecsType.Number, + uint224: RecsType.Number, + uint232: RecsType.Number, + uint240: RecsType.Number, + uint248: RecsType.Number, + uint256: RecsType.Number, + int8: RecsType.Number, + int16: RecsType.Number, + int24: RecsType.Number, + int32: RecsType.Number, + int40: RecsType.Number, + int48: RecsType.Number, + int56: RecsType.Number, + int64: RecsType.Number, + int72: RecsType.Number, + int80: RecsType.Number, + int88: RecsType.Number, + int96: RecsType.Number, + int104: RecsType.Number, + int112: RecsType.Number, + int120: RecsType.Number, + int128: RecsType.Number, + int136: RecsType.Number, + int144: RecsType.Number, + int152: RecsType.Number, + int160: RecsType.Number, + int168: RecsType.Number, + int176: RecsType.Number, + int184: RecsType.Number, + int192: RecsType.Number, + int200: RecsType.Number, + int208: RecsType.Number, + int216: RecsType.Number, + int224: RecsType.Number, + int232: RecsType.Number, + int240: RecsType.Number, + int248: RecsType.Number, + int256: RecsType.Number, + bytes1: RecsType.String, + bytes2: RecsType.String, + bytes3: RecsType.String, + bytes4: RecsType.String, + bytes5: RecsType.String, + bytes6: RecsType.String, + bytes7: RecsType.String, + bytes8: RecsType.String, + bytes9: RecsType.String, + bytes10: RecsType.String, + bytes11: RecsType.String, + bytes12: RecsType.String, + bytes13: RecsType.String, + bytes14: RecsType.String, + bytes15: RecsType.String, + bytes16: RecsType.String, + bytes17: RecsType.String, + bytes18: RecsType.String, + bytes19: RecsType.String, + bytes20: RecsType.String, + bytes21: RecsType.String, + bytes22: RecsType.String, + bytes23: RecsType.String, + bytes24: RecsType.String, + bytes25: RecsType.String, + bytes26: RecsType.String, + bytes27: RecsType.String, + bytes28: RecsType.String, + bytes29: RecsType.String, + bytes30: RecsType.String, + bytes31: RecsType.String, + bytes32: RecsType.String, + bool: RecsType.Boolean, + address: RecsType.String, + "uint8[]": RecsType.NumberArray, + "uint16[]": RecsType.NumberArray, + "uint24[]": RecsType.NumberArray, + "uint32[]": RecsType.NumberArray, + "uint40[]": RecsType.NumberArray, + "uint48[]": RecsType.NumberArray, + "uint56[]": RecsType.NumberArray, + "uint64[]": RecsType.NumberArray, + "uint72[]": RecsType.NumberArray, + "uint80[]": RecsType.NumberArray, + "uint88[]": RecsType.NumberArray, + "uint96[]": RecsType.NumberArray, + "uint104[]": RecsType.NumberArray, + "uint112[]": RecsType.NumberArray, + "uint120[]": RecsType.NumberArray, + "uint128[]": RecsType.NumberArray, + "uint136[]": RecsType.NumberArray, + "uint144[]": RecsType.NumberArray, + "uint152[]": RecsType.NumberArray, + "uint160[]": RecsType.NumberArray, + "uint168[]": RecsType.NumberArray, + "uint176[]": RecsType.NumberArray, + "uint184[]": RecsType.NumberArray, + "uint192[]": RecsType.NumberArray, + "uint200[]": RecsType.NumberArray, + "uint208[]": RecsType.NumberArray, + "uint216[]": RecsType.NumberArray, + "uint224[]": RecsType.NumberArray, + "uint232[]": RecsType.NumberArray, + "uint240[]": RecsType.NumberArray, + "uint248[]": RecsType.NumberArray, + "uint256[]": RecsType.NumberArray, + "int8[]": RecsType.NumberArray, + "int16[]": RecsType.NumberArray, + "int24[]": RecsType.NumberArray, + "int32[]": RecsType.NumberArray, + "int40[]": RecsType.NumberArray, + "int48[]": RecsType.NumberArray, + "int56[]": RecsType.NumberArray, + "int64[]": RecsType.NumberArray, + "int72[]": RecsType.NumberArray, + "int80[]": RecsType.NumberArray, + "int88[]": RecsType.NumberArray, + "int96[]": RecsType.NumberArray, + "int104[]": RecsType.NumberArray, + "int112[]": RecsType.NumberArray, + "int120[]": RecsType.NumberArray, + "int128[]": RecsType.NumberArray, + "int136[]": RecsType.NumberArray, + "int144[]": RecsType.NumberArray, + "int152[]": RecsType.NumberArray, + "int160[]": RecsType.NumberArray, + "int168[]": RecsType.NumberArray, + "int176[]": RecsType.NumberArray, + "int184[]": RecsType.NumberArray, + "int192[]": RecsType.NumberArray, + "int200[]": RecsType.NumberArray, + "int208[]": RecsType.NumberArray, + "int216[]": RecsType.NumberArray, + "int224[]": RecsType.NumberArray, + "int232[]": RecsType.NumberArray, + "int240[]": RecsType.NumberArray, + "int248[]": RecsType.NumberArray, + "int256[]": RecsType.NumberArray, + "bytes1[]": RecsType.StringArray, + "bytes2[]": RecsType.StringArray, + "bytes3[]": RecsType.StringArray, + "bytes4[]": RecsType.StringArray, + "bytes5[]": RecsType.StringArray, + "bytes6[]": RecsType.StringArray, + "bytes7[]": RecsType.StringArray, + "bytes8[]": RecsType.StringArray, + "bytes9[]": RecsType.StringArray, + "bytes10[]": RecsType.StringArray, + "bytes11[]": RecsType.StringArray, + "bytes12[]": RecsType.StringArray, + "bytes13[]": RecsType.StringArray, + "bytes14[]": RecsType.StringArray, + "bytes15[]": RecsType.StringArray, + "bytes16[]": RecsType.StringArray, + "bytes17[]": RecsType.StringArray, + "bytes18[]": RecsType.StringArray, + "bytes19[]": RecsType.StringArray, + "bytes20[]": RecsType.StringArray, + "bytes21[]": RecsType.StringArray, + "bytes22[]": RecsType.StringArray, + "bytes23[]": RecsType.StringArray, + "bytes24[]": RecsType.StringArray, + "bytes25[]": RecsType.StringArray, + "bytes26[]": RecsType.StringArray, + "bytes27[]": RecsType.StringArray, + "bytes28[]": RecsType.StringArray, + "bytes29[]": RecsType.StringArray, + "bytes30[]": RecsType.StringArray, + "bytes31[]": RecsType.StringArray, + "bytes32[]": RecsType.StringArray, + "bool[]": RecsType.T, // no boolean array + "address[]": RecsType.StringArray, + bytes: RecsType.String, + string: RecsType.String, +} as const satisfies Record; diff --git a/packages/recs/src/v2/defineStoreComponents.ts b/packages/recs/src/v2/defineStoreComponents.ts index 5984676aeb..5d7df8f076 100644 --- a/packages/recs/src/v2/defineStoreComponents.ts +++ b/packages/recs/src/v2/defineStoreComponents.ts @@ -10,20 +10,18 @@ import { World, Component } from "../types"; import { Type as RecsType } from "../constants"; import { defineComponent } from "../Component"; -import { SchemaType } from "@latticexyz/schema-type"; -import { schemaTypesToRecsTypes } from "./schemaTypesToRecsTypes"; +import { AbiType } from "@latticexyz/schema-type"; +import { abiTypesToRecsTypes } from "./abiTypesToRecsTypes"; -type SchemaTypeToRecsType = (typeof schemaTypesToRecsTypes)[T]; - -type SchemaOrUserTypeToRecsType = T extends SchemaType - ? SchemaTypeToRecsType +type AbiOrUserTypeToRecsType = T extends AbiType + ? (typeof abiTypesToRecsTypes)[T] : T extends string ? // TODO: better support user enums RecsType.Number : never; type TableSchemaToComponentSchema = { - [K in keyof TableSchema]: SchemaOrUserTypeToRecsType; + [K in keyof TableSchema]: AbiOrUserTypeToRecsType; }; type TablesToComponents> = { @@ -44,23 +42,25 @@ type ExpandSchema = TableSchema exten type ExpandTables = { [K in keyof Tables]: Tables[K] extends TableConfig ? Tables[K] - : Tables[K] extends SchemaType + : Tables[K] extends AbiType ? { schema: { value: Tables[K] } } : Tables[K] extends string ? // TODO: better support for user enums - { schema: { value: SchemaType.UINT256 } } + { schema: { value: "uint8" } } : never; }; +function isAbiType(value: string): value is AbiType { + return value in abiTypesToRecsTypes; +} + const tableSchemaToRecsSchema = ( tableSchema: TableSchema ): TableSchemaToComponentSchema => { return Object.fromEntries( - Object.entries(tableSchema).map(([fieldName, schemaType]) => [ + Object.entries(tableSchema).map(([fieldName, abiType]) => [ fieldName, - typeof schemaType === "string" - ? RecsType.T // TODO: support user enums - : schemaTypesToRecsTypes[schemaType], + isAbiType(abiType) ? abiTypesToRecsTypes[abiType] : RecsType.T, // TODO: support user enums ]) ) as any; }; diff --git a/packages/recs/src/v2/schemaTypesToRecsTypes.ts b/packages/recs/src/v2/schemaTypesToRecsTypes.ts deleted file mode 100644 index 2d6bfe618b..0000000000 --- a/packages/recs/src/v2/schemaTypesToRecsTypes.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { Type as RecsType } from "../constants"; -import { SchemaType } from "@latticexyz/schema-type"; - -export const schemaTypesToRecsTypes = { - [SchemaType.UINT8]: RecsType.Number, - [SchemaType.UINT16]: RecsType.Number, - [SchemaType.UINT24]: RecsType.Number, - [SchemaType.UINT32]: RecsType.Number, - [SchemaType.UINT40]: RecsType.Number, - [SchemaType.UINT48]: RecsType.Number, - [SchemaType.UINT56]: RecsType.Number, - [SchemaType.UINT64]: RecsType.Number, - [SchemaType.UINT72]: RecsType.Number, - [SchemaType.UINT80]: RecsType.Number, - [SchemaType.UINT88]: RecsType.Number, - [SchemaType.UINT96]: RecsType.Number, - [SchemaType.UINT104]: RecsType.Number, - [SchemaType.UINT112]: RecsType.Number, - [SchemaType.UINT120]: RecsType.Number, - [SchemaType.UINT128]: RecsType.Number, - [SchemaType.UINT136]: RecsType.Number, - [SchemaType.UINT144]: RecsType.Number, - [SchemaType.UINT152]: RecsType.Number, - [SchemaType.UINT160]: RecsType.Number, - [SchemaType.UINT168]: RecsType.Number, - [SchemaType.UINT176]: RecsType.Number, - [SchemaType.UINT184]: RecsType.Number, - [SchemaType.UINT192]: RecsType.Number, - [SchemaType.UINT200]: RecsType.Number, - [SchemaType.UINT208]: RecsType.Number, - [SchemaType.UINT216]: RecsType.Number, - [SchemaType.UINT224]: RecsType.Number, - [SchemaType.UINT232]: RecsType.Number, - [SchemaType.UINT240]: RecsType.Number, - [SchemaType.UINT248]: RecsType.Number, - [SchemaType.UINT256]: RecsType.Number, - [SchemaType.INT8]: RecsType.Number, - [SchemaType.INT16]: RecsType.Number, - [SchemaType.INT24]: RecsType.Number, - [SchemaType.INT32]: RecsType.Number, - [SchemaType.INT40]: RecsType.Number, - [SchemaType.INT48]: RecsType.Number, - [SchemaType.INT56]: RecsType.Number, - [SchemaType.INT64]: RecsType.Number, - [SchemaType.INT72]: RecsType.Number, - [SchemaType.INT80]: RecsType.Number, - [SchemaType.INT88]: RecsType.Number, - [SchemaType.INT96]: RecsType.Number, - [SchemaType.INT104]: RecsType.Number, - [SchemaType.INT112]: RecsType.Number, - [SchemaType.INT120]: RecsType.Number, - [SchemaType.INT128]: RecsType.Number, - [SchemaType.INT136]: RecsType.Number, - [SchemaType.INT144]: RecsType.Number, - [SchemaType.INT152]: RecsType.Number, - [SchemaType.INT160]: RecsType.Number, - [SchemaType.INT168]: RecsType.Number, - [SchemaType.INT176]: RecsType.Number, - [SchemaType.INT184]: RecsType.Number, - [SchemaType.INT192]: RecsType.Number, - [SchemaType.INT200]: RecsType.Number, - [SchemaType.INT208]: RecsType.Number, - [SchemaType.INT216]: RecsType.Number, - [SchemaType.INT224]: RecsType.Number, - [SchemaType.INT232]: RecsType.Number, - [SchemaType.INT240]: RecsType.Number, - [SchemaType.INT248]: RecsType.Number, - [SchemaType.INT256]: RecsType.Number, - [SchemaType.BYTES1]: RecsType.String, - [SchemaType.BYTES2]: RecsType.String, - [SchemaType.BYTES3]: RecsType.String, - [SchemaType.BYTES4]: RecsType.String, - [SchemaType.BYTES5]: RecsType.String, - [SchemaType.BYTES6]: RecsType.String, - [SchemaType.BYTES7]: RecsType.String, - [SchemaType.BYTES8]: RecsType.String, - [SchemaType.BYTES9]: RecsType.String, - [SchemaType.BYTES10]: RecsType.String, - [SchemaType.BYTES11]: RecsType.String, - [SchemaType.BYTES12]: RecsType.String, - [SchemaType.BYTES13]: RecsType.String, - [SchemaType.BYTES14]: RecsType.String, - [SchemaType.BYTES15]: RecsType.String, - [SchemaType.BYTES16]: RecsType.String, - [SchemaType.BYTES17]: RecsType.String, - [SchemaType.BYTES18]: RecsType.String, - [SchemaType.BYTES19]: RecsType.String, - [SchemaType.BYTES20]: RecsType.String, - [SchemaType.BYTES21]: RecsType.String, - [SchemaType.BYTES22]: RecsType.String, - [SchemaType.BYTES23]: RecsType.String, - [SchemaType.BYTES24]: RecsType.String, - [SchemaType.BYTES25]: RecsType.String, - [SchemaType.BYTES26]: RecsType.String, - [SchemaType.BYTES27]: RecsType.String, - [SchemaType.BYTES28]: RecsType.String, - [SchemaType.BYTES29]: RecsType.String, - [SchemaType.BYTES30]: RecsType.String, - [SchemaType.BYTES31]: RecsType.String, - [SchemaType.BYTES32]: RecsType.String, - [SchemaType.BOOL]: RecsType.Boolean, - [SchemaType.ADDRESS]: RecsType.String, - [SchemaType.UINT8_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT16_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT24_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT32_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT40_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT48_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT56_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT64_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT72_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT80_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT88_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT96_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT104_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT112_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT120_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT128_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT136_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT144_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT152_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT160_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT168_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT176_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT184_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT192_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT200_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT208_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT216_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT224_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT232_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT240_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT248_ARRAY]: RecsType.NumberArray, - [SchemaType.UINT256_ARRAY]: RecsType.NumberArray, - [SchemaType.INT8_ARRAY]: RecsType.NumberArray, - [SchemaType.INT16_ARRAY]: RecsType.NumberArray, - [SchemaType.INT24_ARRAY]: RecsType.NumberArray, - [SchemaType.INT32_ARRAY]: RecsType.NumberArray, - [SchemaType.INT40_ARRAY]: RecsType.NumberArray, - [SchemaType.INT48_ARRAY]: RecsType.NumberArray, - [SchemaType.INT56_ARRAY]: RecsType.NumberArray, - [SchemaType.INT64_ARRAY]: RecsType.NumberArray, - [SchemaType.INT72_ARRAY]: RecsType.NumberArray, - [SchemaType.INT80_ARRAY]: RecsType.NumberArray, - [SchemaType.INT88_ARRAY]: RecsType.NumberArray, - [SchemaType.INT96_ARRAY]: RecsType.NumberArray, - [SchemaType.INT104_ARRAY]: RecsType.NumberArray, - [SchemaType.INT112_ARRAY]: RecsType.NumberArray, - [SchemaType.INT120_ARRAY]: RecsType.NumberArray, - [SchemaType.INT128_ARRAY]: RecsType.NumberArray, - [SchemaType.INT136_ARRAY]: RecsType.NumberArray, - [SchemaType.INT144_ARRAY]: RecsType.NumberArray, - [SchemaType.INT152_ARRAY]: RecsType.NumberArray, - [SchemaType.INT160_ARRAY]: RecsType.NumberArray, - [SchemaType.INT168_ARRAY]: RecsType.NumberArray, - [SchemaType.INT176_ARRAY]: RecsType.NumberArray, - [SchemaType.INT184_ARRAY]: RecsType.NumberArray, - [SchemaType.INT192_ARRAY]: RecsType.NumberArray, - [SchemaType.INT200_ARRAY]: RecsType.NumberArray, - [SchemaType.INT208_ARRAY]: RecsType.NumberArray, - [SchemaType.INT216_ARRAY]: RecsType.NumberArray, - [SchemaType.INT224_ARRAY]: RecsType.NumberArray, - [SchemaType.INT232_ARRAY]: RecsType.NumberArray, - [SchemaType.INT240_ARRAY]: RecsType.NumberArray, - [SchemaType.INT248_ARRAY]: RecsType.NumberArray, - [SchemaType.INT256_ARRAY]: RecsType.NumberArray, - [SchemaType.BYTES1_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES2_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES3_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES4_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES5_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES6_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES7_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES8_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES9_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES10_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES11_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES12_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES13_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES14_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES15_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES16_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES17_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES18_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES19_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES20_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES21_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES22_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES23_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES24_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES25_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES26_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES27_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES28_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES29_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES30_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES31_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES32_ARRAY]: RecsType.StringArray, - [SchemaType.BOOL_ARRAY]: RecsType.T, // no boolean array - [SchemaType.ADDRESS_ARRAY]: RecsType.StringArray, - [SchemaType.BYTES]: RecsType.String, - [SchemaType.STRING]: RecsType.String, -} as const satisfies Record; From 282163c3ba0ac694d5e06e2f2d46003fd752ed26 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 18 Mar 2023 01:17:27 +0300 Subject: [PATCH 5/7] refactor(cli): flatten userTypes and require them when used in tables --- packages/cli/scripts/codegen.ts | 8 +-- .../cli/src/config/parseStoreConfig.test-d.ts | 6 +- packages/cli/src/config/parseStoreConfig.ts | 56 +++++++++++-------- .../render-solidity/renderTypesFromConfig.ts | 4 +- .../cli/src/render-solidity/tableOptions.ts | 8 +-- packages/cli/src/render-solidity/tablegen.ts | 4 +- packages/cli/src/render-solidity/userType.ts | 12 ++-- packages/cli/src/utils/deploy-v2.ts | 4 +- packages/world/mud.config.mts | 6 +- 9 files changed, 56 insertions(+), 52 deletions(-) diff --git a/packages/cli/scripts/codegen.ts b/packages/cli/scripts/codegen.ts index 3b138c1580..4a6c3a73f8 100644 --- a/packages/cli/scripts/codegen.ts +++ b/packages/cli/scripts/codegen.ts @@ -28,11 +28,9 @@ const config = defineStoreUserConfig({ }, }, - userTypes: { - enums: { - Enum1: ["E1", "E2", "E3"], - Enum2: ["E1"], - }, + enums: { + Enum1: ["E1", "E2", "E3"], + Enum2: ["E1"], }, }); diff --git a/packages/cli/src/config/parseStoreConfig.test-d.ts b/packages/cli/src/config/parseStoreConfig.test-d.ts index 14072ccb4b..3abb3772de 100644 --- a/packages/cli/src/config/parseStoreConfig.test-d.ts +++ b/packages/cli/src/config/parseStoreConfig.test-d.ts @@ -1,14 +1,14 @@ import { describe, expectTypeOf } from "vitest"; import { z } from "zod"; -import { StoreConfig, StoreUserConfig, UserTypesConfig } from "./parseStoreConfig.js"; +import { StoreConfig, StoreUserConfig } from "./parseStoreConfig.js"; describe("StoreUserConfig", () => { // Typecheck manual interfaces against zod expectTypeOf().toEqualTypeOf>(); // type equality isn't deep for optionals expectTypeOf().toEqualTypeOf["tables"][string]>(); - expectTypeOf["enums"]>[string]>().toEqualTypeOf< - NonNullable>["enums"]>[string] + expectTypeOf[string]>().toEqualTypeOf< + NonNullable>["enums"]>[string] >(); // TODO If more nested schemas are added, provide separate tests for them }); diff --git a/packages/cli/src/config/parseStoreConfig.ts b/packages/cli/src/config/parseStoreConfig.ts index 767d42ac78..8ca805ea66 100644 --- a/packages/cli/src/config/parseStoreConfig.ts +++ b/packages/cli/src/config/parseStoreConfig.ts @@ -130,19 +130,25 @@ export const zTablesConfig = z.record(TableName, zTableConfig).transform((tables * ************************************************************************/ -export interface UserTypesConfig { - /** Path to the file where common types will be generated and imported from. Default is "Types" */ - path?: string; - /** Enum names mapped to lists of their member names */ - enums?: Record; -} - -export const zUserTypesConfig = z - .object({ - path: z.string().default("Types"), - enums: z.record(UserEnumName, UserEnum).default({}), - }) - .default({}); +export type EnumsConfig = string extends EnumNames + ? { + /** + * Enum names mapped to lists of their member names + */ + enums?: Record; + } + : { + /** + * Enum names mapped to lists of their member names + * + * Required if used in tables + */ + enums: Record; + }; + +export const zEnumsConfig = z.object({ + enums: z.record(UserEnumName, UserEnum).default({}), +}); /************************************************************************ * @@ -151,7 +157,7 @@ export const zUserTypesConfig = z ************************************************************************/ // zod doesn't preserve doc comments -export interface StoreUserConfig { +export type StoreUserConfig = EnumsConfig & { /** The namespace for table ids. Default is "" (empty string) */ namespace?: string; /** Path for store package imports. Default is "@latticexyz/store/src/" */ @@ -166,9 +172,9 @@ export interface StoreUserConfig; - /** User-defined types that will be generated and may be used in table schemas instead of abi types */ - userTypes?: UserTypesConfig; -} + /** Path to the file where common user types will be generated and imported from. Default is "Types" */ + userTypesPath?: string; +}; /** Type helper for defining StoreUserConfig */ export function defineStoreUserConfig( @@ -179,12 +185,14 @@ export function defineStoreUserConfig; -const StoreConfigUnrefined = z.object({ - namespace: Selector.default(""), - storeImportPath: z.string().default("@latticexyz/store/src/"), - tables: zTablesConfig, - userTypes: zUserTypesConfig, -}); +const StoreConfigUnrefined = z + .object({ + namespace: Selector.default(""), + storeImportPath: z.string().default("@latticexyz/store/src/"), + tables: zTablesConfig, + userTypesPath: z.string().default("Types"), + }) + .merge(zEnumsConfig); // finally validate global conditions export const StoreConfig = StoreConfigUnrefined.superRefine(validateStoreConfig); @@ -215,7 +223,7 @@ function validateStoreConfig(config: z.output, ctx: } // Global names must be unique const tableNames = Object.keys(config.tables); - const userTypeNames = Object.keys(config.userTypes.enums); + const userTypeNames = Object.keys(config.enums); const globalNames = [...tableNames, ...userTypeNames]; const duplicateGlobalNames = getDuplicates(globalNames); if (duplicateGlobalNames.length > 0) { diff --git a/packages/cli/src/render-solidity/renderTypesFromConfig.ts b/packages/cli/src/render-solidity/renderTypesFromConfig.ts index 19d6f9923e..77f95cce6d 100644 --- a/packages/cli/src/render-solidity/renderTypesFromConfig.ts +++ b/packages/cli/src/render-solidity/renderTypesFromConfig.ts @@ -2,9 +2,9 @@ import { StoreConfig } from "../config/parseStoreConfig.js"; import { renderTypes } from "./renderTypes.js"; export function renderTypesFromConfig(config: StoreConfig) { - const enums = Object.keys(config.userTypes.enums).map((name) => ({ + const enums = Object.keys(config.enums).map((name) => ({ name, - memberNames: config.userTypes.enums[name], + memberNames: config.enums[name], })); return renderTypes({ diff --git a/packages/cli/src/render-solidity/tableOptions.ts b/packages/cli/src/render-solidity/tableOptions.ts index 1ff4fd7e05..eaea9e05e5 100644 --- a/packages/cli/src/render-solidity/tableOptions.ts +++ b/packages/cli/src/render-solidity/tableOptions.ts @@ -35,9 +35,9 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { const primaryKeys = Object.keys(tableData.primaryKeys).map((name) => { const abiOrUserType = tableData.primaryKeys[name]; - const { renderTableType } = resolveAbiOrUserType(abiOrUserType, config.userTypes); + const { renderTableType } = resolveAbiOrUserType(abiOrUserType, config); - const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config.userTypes); + const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config); if (importDatum) imports.push(importDatum); if (renderTableType.isDynamic) @@ -53,9 +53,9 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { const fields = Object.keys(tableData.schema).map((name) => { const abiOrUserType = tableData.schema[name]; - const { renderTableType, schemaType } = resolveAbiOrUserType(abiOrUserType, config.userTypes); + const { renderTableType, schemaType } = resolveAbiOrUserType(abiOrUserType, config); - const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config.userTypes); + const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config); if (importDatum) imports.push(importDatum); const elementType = SchemaTypeArrayToElement[schemaType]; diff --git a/packages/cli/src/render-solidity/tablegen.ts b/packages/cli/src/render-solidity/tablegen.ts index 67c0de6a2d..e72d9cd827 100644 --- a/packages/cli/src/render-solidity/tablegen.ts +++ b/packages/cli/src/render-solidity/tablegen.ts @@ -16,8 +16,8 @@ export async function tablegen(config: StoreConfig, outputBaseDirectory: string) } // write types to file - if (Object.keys(config.userTypes.enums).length > 0) { - const fullOutputPath = path.join(outputBaseDirectory, `${config.userTypes.path}.sol`); + if (Object.keys(config.enums).length > 0) { + const fullOutputPath = path.join(outputBaseDirectory, `${config.userTypesPath}.sol`); const output = renderTypesFromConfig(config); formatAndWrite(output, fullOutputPath, "Generated types file"); } diff --git a/packages/cli/src/render-solidity/userType.ts b/packages/cli/src/render-solidity/userType.ts index 977ba2ff16..feae7d3b31 100644 --- a/packages/cli/src/render-solidity/userType.ts +++ b/packages/cli/src/render-solidity/userType.ts @@ -7,7 +7,7 @@ export type UserTypeInfo = ReturnType; /** * Resolve an abi or user type into a SchemaType */ -export function resolveAbiOrUserType(abiOrUserType: string, userTypesConfig: StoreConfig["userTypes"]) { +export function resolveAbiOrUserType(abiOrUserType: string, config: StoreConfig) { if (abiOrUserType in AbiTypeToSchemaType) { const schemaType = AbiTypeToSchemaType[abiOrUserType]; return { @@ -15,7 +15,7 @@ export function resolveAbiOrUserType(abiOrUserType: string, userTypesConfig: Sto renderTableType: getSchemaTypeInfo(schemaType), }; } else { - const { schemaType, renderTableType } = getUserTypeInfo(abiOrUserType, userTypesConfig); + const { schemaType, renderTableType } = getUserTypeInfo(abiOrUserType, config); return { schemaType, renderTableType }; } } @@ -26,14 +26,14 @@ export function resolveAbiOrUserType(abiOrUserType: string, userTypesConfig: Sto export function importForAbiOrUserType( abiOrUserType: string, usedInDirectory: string, - userTypesConfig: StoreConfig["userTypes"] + config: StoreConfig ): ImportDatum | undefined { if (abiOrUserType in AbiTypeToSchemaType) { return undefined; } else { return { symbol: abiOrUserType, - fromPath: userTypesConfig.path + ".sol", + fromPath: config.userTypesPath + ".sol", usedInPath: usedInDirectory, }; } @@ -57,12 +57,12 @@ export function getSchemaTypeInfo(schemaType: SchemaType): RenderTableType { export function getUserTypeInfo( userType: string, - userTypesConfig: StoreConfig["userTypes"] + config: StoreConfig ): { schemaType: SchemaType; renderTableType: RenderTableType; } { - if (userType in userTypesConfig.enums) { + if (userType in config.enums) { const schemaType = SchemaType.UINT8; const staticByteLength = getStaticByteLength(schemaType); const isDynamic = staticByteLength === 0; diff --git a/packages/cli/src/utils/deploy-v2.ts b/packages/cli/src/utils/deploy-v2.ts index 497bb99120..545b164361 100644 --- a/packages/cli/src/utils/deploy-v2.ts +++ b/packages/cli/src/utils/deploy-v2.ts @@ -121,12 +121,12 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): // Register table const schemaTypes = Object.values(schema).map((abiOrUserType) => { - const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig.userTypes); + const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig); return schemaType; }); const keyTypes = Object.values(primaryKeys).map((abiOrUserType) => { - const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig.userTypes); + const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig); return schemaType; }); diff --git a/packages/world/mud.config.mts b/packages/world/mud.config.mts index f9c1287743..575f22c243 100644 --- a/packages/world/mud.config.mts +++ b/packages/world/mud.config.mts @@ -105,9 +105,7 @@ export default defineMUDUserConfig({ storeArgument: true, }, }, - userTypes: { - enums: { - Resource: ["NONE", "NAMESPACE", "TABLE", "SYSTEM"], - }, + enums: { + Resource: ["NONE", "NAMESPACE", "TABLE", "SYSTEM"], }, }); From aef0586dfbc2c044a6097c4098d75ae592ec7de4 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 18 Mar 2023 01:39:47 +0300 Subject: [PATCH 6/7] fix(cli): improve validation for columns and keys --- packages/cli/src/config/commonSchemas.ts | 9 -------- packages/cli/src/config/parseStoreConfig.ts | 23 +++++++++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/cli/src/config/commonSchemas.ts b/packages/cli/src/config/commonSchemas.ts index 0ee5806c26..4f0397d44c 100644 --- a/packages/cli/src/config/commonSchemas.ts +++ b/packages/cli/src/config/commonSchemas.ts @@ -31,14 +31,5 @@ export const BaseRoute = z.string().superRefine(validateBaseRoute); /** A valid Ethereum address */ export const EthereumAddress = z.string().superRefine(validateEthereumAddress); -export const zAbiType = z - .string() - .refine((val): val is AbiType => (AbiTypes as string[]).includes(val), "Invalid abi type"); - -/** Static subset of SchemaType enum */ -export const zStaticAbiType = z - .string() - .refine((val): val is AbiType => (StaticAbiTypes as string[]).includes(val), "Abi type must be static"); - /** A selector for namespace/file/resource */ export const Selector = z.string().superRefine(validateSelector); diff --git a/packages/cli/src/config/parseStoreConfig.ts b/packages/cli/src/config/parseStoreConfig.ts index 8ca805ea66..b8c3e7f199 100644 --- a/packages/cli/src/config/parseStoreConfig.ts +++ b/packages/cli/src/config/parseStoreConfig.ts @@ -1,7 +1,7 @@ -import { AbiType, AbiTypes, StaticAbiType } from "@latticexyz/schema-type"; +import { AbiType, AbiTypes, StaticAbiType, StaticAbiTypes } from "@latticexyz/schema-type"; import { RefinementCtx, z, ZodIssueCode } from "zod"; import { RequireKeys, StringForUnion } from "../utils/typeUtils.js"; -import { ObjectName, Selector, zAbiType, zStaticAbiType, UserEnum, ValueName } from "./commonSchemas.js"; +import { ObjectName, Selector, UserEnum, ValueName } from "./commonSchemas.js"; import { getDuplicates } from "./validation.js"; const TableName = ObjectName; @@ -11,12 +11,13 @@ const UserEnumName = ObjectName; // Fields can use AbiType or one of user-defined wrapper types // (user types are refined later, based on the appropriate config options) -const zFieldData = z.union([zAbiType, z.string()]); +const zFieldData = z.string(); type FieldData = AbiType | UserTypes; // Primary keys allow only static types -const zPrimaryKey = z.union([zStaticAbiType, z.string()]); +// (user types are refined later, based on the appropriate config options) +const zPrimaryKey = z.string(); const zPrimaryKeys = z.record(KeyName, zPrimaryKey).default({ key: "bytes32" }); type PrimaryKey = StaticAbiType | StaticUserTypes; @@ -223,7 +224,8 @@ function validateStoreConfig(config: z.output, ctx: } // Global names must be unique const tableNames = Object.keys(config.tables); - const userTypeNames = Object.keys(config.enums); + const staticUserTypeNames = Object.keys(config.enums); + const userTypeNames = staticUserTypeNames; const globalNames = [...tableNames, ...userTypeNames]; const duplicateGlobalNames = getDuplicates(globalNames); if (duplicateGlobalNames.length > 0) { @@ -235,7 +237,7 @@ function validateStoreConfig(config: z.output, ctx: // User types must exist for (const table of Object.values(config.tables)) { for (const primaryKeyType of Object.values(table.primaryKeys)) { - validateAbiOrUserType(userTypeNames, primaryKeyType, ctx); + validateStaticAbiOrUserType(staticUserTypeNames, primaryKeyType, ctx); } for (const fieldType of Object.values(table.schema)) { validateAbiOrUserType(userTypeNames, fieldType, ctx); @@ -251,3 +253,12 @@ function validateAbiOrUserType(userTypeNames: string[], type: string, ctx: Refin }); } } + +function validateStaticAbiOrUserType(staticUserTypeNames: string[], type: string, ctx: RefinementCtx) { + if (!(StaticAbiTypes as string[]).includes(type) && !staticUserTypeNames.includes(type)) { + ctx.addIssue({ + code: ZodIssueCode.custom, + message: `${type} is not a static type`, + }); + } +} From d7fb8a3f0ba09ffbd0bdaefc111d8c6800c68156 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 18 Mar 2023 01:42:37 +0300 Subject: [PATCH 7/7] refactor(cli): shorten config function names --- packages/cli/scripts/codegen.ts | 4 ++-- packages/cli/src/config/index.ts | 4 +--- packages/cli/src/config/parseStoreConfig.ts | 4 +--- packages/cli/src/index.ts | 2 +- packages/store/mud.config.mts | 4 ++-- packages/world/mud.config.mts | 4 ++-- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/cli/scripts/codegen.ts b/packages/cli/scripts/codegen.ts index 4a6c3a73f8..ae3b92d2fe 100644 --- a/packages/cli/scripts/codegen.ts +++ b/packages/cli/scripts/codegen.ts @@ -1,10 +1,10 @@ -import { defineStoreUserConfig, parseStoreConfig } from "../src/config/index.js"; +import { storeConfig, parseStoreConfig } from "../src/config/index.js"; import { tablegen } from "../src/render-solidity/tablegen.js"; import { logError } from "../src/utils/errors.js"; import { getSrcDirectory } from "../src/utils/foundry.js"; // This config is used only for tests -const config = defineStoreUserConfig({ +const config = storeConfig({ tables: { Table1: { primaryKeys: { diff --git a/packages/cli/src/config/index.ts b/packages/cli/src/config/index.ts index 5b92ed8112..295870fc2a 100644 --- a/packages/cli/src/config/index.ts +++ b/packages/cli/src/config/index.ts @@ -7,9 +7,7 @@ export type MUDUserConfig = S export type MUDConfig = StoreConfig & ResolvedWorldConfig; /** Type helper for defining MUDUserConfig */ -export function defineMUDUserConfig( - config: MUDUserConfig -) { +export function mudConfig(config: MUDUserConfig) { return config; } diff --git a/packages/cli/src/config/parseStoreConfig.ts b/packages/cli/src/config/parseStoreConfig.ts index b8c3e7f199..fad88a5011 100644 --- a/packages/cli/src/config/parseStoreConfig.ts +++ b/packages/cli/src/config/parseStoreConfig.ts @@ -178,9 +178,7 @@ export type StoreUserConfig = }; /** Type helper for defining StoreUserConfig */ -export function defineStoreUserConfig( - config: StoreUserConfig -) { +export function storeConfig(config: StoreUserConfig) { return config; } diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 714cb4fb6e..1ffdc3c282 100755 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -13,7 +13,7 @@ export type { MUDUserConfig, MUDConfig, } from "./config/index.js"; -export { defineStoreUserConfig, defineMUDUserConfig } from "./config/index.js"; +export { storeConfig, mudConfig } from "./config/index.js"; export * from "./constants.js"; export * from "./utils/index.js"; diff --git a/packages/store/mud.config.mts b/packages/store/mud.config.mts index 4e73eff471..a7d93c43c7 100644 --- a/packages/store/mud.config.mts +++ b/packages/store/mud.config.mts @@ -1,6 +1,6 @@ -import { defineStoreUserConfig } from "@latticexyz/cli"; +import { storeConfig } from "@latticexyz/cli"; -export default defineStoreUserConfig({ +export default storeConfig({ storeImportPath: "../", namespace: "mudstore", tables: { diff --git a/packages/world/mud.config.mts b/packages/world/mud.config.mts index 575f22c243..a281cd3e2c 100644 --- a/packages/world/mud.config.mts +++ b/packages/world/mud.config.mts @@ -1,6 +1,6 @@ -import { defineMUDUserConfig } from "@latticexyz/cli"; +import { mudConfig } from "@latticexyz/cli"; -export default defineMUDUserConfig({ +export default mudConfig({ worldImportPath: "../", worldgenDirectory: "interfaces", tables: {