Skip to content

Commit

Permalink
refactor(world): add validateNamespace helper (latticexyz#2894)
Browse files Browse the repository at this point in the history
  • Loading branch information
yonadaaa authored Jun 6, 2024
1 parent 254d1a7 commit e0c9eaa
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 11 deletions.
30 changes: 21 additions & 9 deletions packages/world/ts/config/v2/namespaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
extendedScope,
getPath,
} from "@latticexyz/store/config/v2";
import { NamespacesInput } from "./input";
import { NamespaceInput, NamespacesInput } from "./input";
import { ErrorMessage, conform } from "@arktype/util";

export type namespacedTableKeys<world> = world extends { namespaces: infer namespaces }
? {
Expand All @@ -19,12 +20,25 @@ export type namespacedTableKeys<world> = world extends { namespaces: infer names
}[keyof namespaces]
: never;

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

export function validateNamespace<scope extends Scope = AbiTypeScope>(
namespace: unknown,
scope: scope,
): asserts namespace is NamespaceInput {
if (hasOwnKey(namespace, "tables")) {
validateTables(namespace.tables, scope);
}
}

export type validateNamespaces<namespaces, scope extends Scope = AbiTypeScope> = {
[namespace in keyof namespaces]: {
[key in keyof namespaces[namespace]]: key extends "tables"
? validateTables<namespaces[namespace][key], scope>
: namespaces[namespace][key];
};
[namespace in keyof namespaces]: validateNamespace<namespaces[namespace], scope>;
};

export function validateNamespaces<scope extends Scope = AbiTypeScope>(
Expand All @@ -35,9 +49,7 @@ export function validateNamespaces<scope extends Scope = AbiTypeScope>(
throw new Error(`Expected namespaces, received ${JSON.stringify(namespaces)}`);
}
for (const namespace of Object.values(namespaces)) {
if (hasOwnKey(namespace, "tables")) {
validateTables(namespace.tables, scope);
}
validateNamespace(namespace, scope);
}
}

Expand Down
28 changes: 28 additions & 0 deletions packages/world/ts/config/v2/worldWithShorthands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,4 +353,32 @@ describe("defineWorldWithShorthands", () => {

defineWorldWithShorthands(config);
});

it("should throw with an invalid namespace config option", () => {
attest(() =>
defineWorldWithShorthands({
namespaces: {
ExampleNamespace: {
tables: {
// @ts-expect-error Type '"number"' is not assignable to type 'AbiType'.
ExampleTable: "number",
},
},
},
}),
).type.errors(`Type '"number"' is not assignable to type 'AbiType'.`);
});

it("should throw with a non-existent namespace config option", () => {
attest(() =>
defineWorldWithShorthands({
namespaces: {
ExampleNamespace: {
// @ts-expect-error Type 'true' is not assignable to type '"`invalidProperty` is not a valid namespace config option.
invalidProperty: true,
},
},
}),
).type.errors("`invalidProperty` is not a valid namespace config option.");
});
});
4 changes: 2 additions & 2 deletions packages/world/ts/config/v2/worldWithShorthands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
validateTablesWithShorthands,
} from "@latticexyz/store/config/v2";
import { WorldWithShorthandsInput } from "./input";
import { validateNamespaces } from "./namespaces";
import { validateNamespace } from "./namespaces";
import { resolveWorld, validateWorld } from "./world";

export type resolveWorldWithShorthands<world> = resolveWorld<{
Expand Down Expand Up @@ -54,7 +54,7 @@ export type validateNamespacesWithShorthands<namespaces, scope extends Scope = A
[namespace in keyof namespaces]: {
[key in keyof namespaces[namespace]]: key extends "tables"
? validateTablesWithShorthands<namespaces[namespace][key], scope>
: validateNamespaces<namespaces[namespace], scope>[key];
: validateNamespace<namespaces[namespace], scope>[key];
};
};

Expand Down

0 comments on commit e0c9eaa

Please sign in to comment.