Skip to content

Commit

Permalink
feat(store,world): add namespaces to config output (#2958)
Browse files Browse the repository at this point in the history
  • Loading branch information
holic authored Jul 18, 2024
1 parent 8f6fa58 commit 69e23a3
Show file tree
Hide file tree
Showing 12 changed files with 574 additions and 260 deletions.
18 changes: 15 additions & 3 deletions packages/store/ts/config/v2/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,28 @@ export type TablesInput = {

export type CodegenInput = Partial<Codegen>;

export type StoreInput = {
export type NamespaceInput = {
/**
* Human-readable namespace label. Used as config keys and directory names.
* Labels are not length constrained like namespaces within resource IDs, but special characters should be avoided to be compatible with the filesystem, Solidity compiler, etc.
*/
readonly label: string;
/**
* Namespace used in resource ID.
* Defaults to the first 16 characters of `label` if not set.
*/
readonly namespace?: string;
readonly tables?: TablesInput;
};

export type StoreInput = Omit<NamespaceInput, "label"> & {
/**
* Directory of Solidity source relative to the MUD config.
* This is used to resolve other paths in the config, like codegen and user types.
*
* Defaults to `src` to match `foundry.toml`'s default. If you change this from the default, you may also need to configure foundry with the same source directory.
*/
readonly sourceDirectory?: string;
readonly namespace?: string;
readonly tables?: TablesInput;
readonly userTypes?: UserTypes;
readonly enums?: EnumsInput;
readonly codegen?: CodegenInput;
Expand Down
61 changes: 61 additions & 0 deletions packages/store/ts/config/v2/namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { ErrorMessage, flatMorph } from "@arktype/util";
import { hasOwnKey, mergeIfUndefined } from "./generics";
import { NamespaceInput } from "./input";
import { resolveTables, validateTables } from "./tables";
import { AbiTypeScope, Scope } from "./scope";

export type validateNamespace<input, scope extends Scope = AbiTypeScope> = {
[key in keyof input]: key extends "tables"
? validateTables<input[key], scope>
: key extends keyof NamespaceInput
? NamespaceInput[key]
: ErrorMessage<`\`${key & string}\` is not a valid namespace config option.`>;
};

export function validateNamespace<scope extends Scope = AbiTypeScope>(
input: unknown,
scope: scope,
): asserts input is NamespaceInput {
if (hasOwnKey(input, "namespace") && typeof input.namespace === "string" && input.namespace.length > 14) {
throw new Error(`\`namespace\` must fit into a \`bytes14\`, but "${input.namespace}" is too long.`);
}
if (hasOwnKey(input, "tables")) {
validateTables(input.tables, scope);
}
}

export type resolveNamespace<input, scope extends Scope = AbiTypeScope> = input extends NamespaceInput
? {
readonly label: input["label"];
readonly namespace: string;
readonly tables: undefined extends input["tables"]
? {}
: resolveTables<
{
readonly [label in keyof input["tables"]]: mergeIfUndefined<
input["tables"][label],
{ readonly namespace: string }
>;
},
scope
>;
}
: never;

export function resolveNamespace<const input extends NamespaceInput, scope extends Scope = AbiTypeScope>(
input: input,
scope: scope,
): resolveNamespace<input, scope> {
const label = input.label;
const namespace = input.namespace ?? label.slice(0, 14);
return {
label,
namespace,
tables: resolveTables(
flatMorph(input.tables ?? {}, (label, table) => {
return [label, mergeIfUndefined(table, { namespace })];
}),
scope,
),
} as never;
}
24 changes: 19 additions & 5 deletions packages/store/ts/config/v2/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,34 @@ export type Codegen = {
readonly indexFilename: string;
};

export type Store = {
export type Namespace = {
/**
* Human-readable namespace label. Used as config keys and directory names.
* Labels are not length constrained like namespaces within resource IDs, but special characters should be avoided to be compatible with the filesystem, Solidity compiler, etc.
*/
readonly label: string;
/**
* Namespace used in resource ID.
*/
readonly namespace: string;
readonly tables: Tables;
};

export type Namespaces = {
readonly [label: string]: Namespace;
};

export type Store = Omit<Namespace, "label"> & {
/**
* Directory of Solidity source relative to the MUD config.
* This is used to resolve other paths in the config, like codegen and user types.
*
* Defaults to `src` to match `foundry.toml`'s default. If you change this from the default, you may also need to configure foundry with the same source directory.
*/
readonly sourceDirectory: string;
readonly tables: {
readonly [label: string]: Table;
};
readonly userTypes: UserTypes;
readonly enums: EnumsInput;
readonly enumValues: EnumValues;
readonly namespace: string;
readonly codegen: Codegen;
readonly namespaces: Namespaces;
};
Loading

0 comments on commit 69e23a3

Please sign in to comment.